@nylorun/runtime 0.23.0-beta → 0.24.0-beta
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/CHANGELOG.md +148 -0
- package/README.md +79 -28
- package/dist/adapters/execution/restate.js +1 -1
- package/dist/adapters/replication/pgoutput.d.ts +2 -0
- package/dist/adapters/replication/pgoutput.js +6 -3
- package/dist/adapters/sandbox/local.d.ts +9 -1
- package/dist/adapters/sandbox/local.js +16 -4
- package/dist/adapters/sandbox/virtual.js +4 -1
- package/dist/api/a2a/endpoint.js +5 -1
- package/dist/api/a2a/routes.d.ts +2 -0
- package/dist/api/a2a/routes.js +2 -2
- package/dist/api/a2a/tasks.js +2 -1
- package/dist/api/ag-ui/endpoint.js +4 -2
- package/dist/api/ag-ui/history.js +4 -1
- package/dist/api/ag-ui/routes.d.ts +4 -1
- package/dist/api/ag-ui/routes.js +11 -10
- package/dist/api/ag-ui/translate.js +3 -2
- package/dist/api/components.d.ts +4953 -1204
- package/dist/api/components.js +25 -16
- package/dist/api/gate/keys.js +7 -1
- package/dist/api/gate/routes.d.ts +6 -0
- package/dist/api/gate/routes.js +39 -3
- package/dist/api/http/app.js +4 -4
- package/dist/api/http/define.d.ts +6 -0
- package/dist/api/http/define.js +13 -1
- package/dist/api/http/respond.js +1 -1
- package/dist/api/http/routes/artifacts.js +35 -8
- package/dist/api/http/routes/coverage.d.ts +9 -0
- package/dist/api/http/routes/coverage.js +34 -0
- package/dist/api/http/routes/environments.d.ts +11 -0
- package/dist/api/http/routes/environments.js +283 -0
- package/dist/api/http/routes/mcp.d.ts +1 -1
- package/dist/api/http/routes/mcp.js +2 -2
- package/dist/api/http/routes/me.js +1 -1
- package/dist/api/http/routes/reads.d.ts +45 -9
- package/dist/api/http/routes/reads.js +54 -5
- package/dist/api/http/routes/sessions.js +11 -6
- package/dist/api/http/routes/tenant.js +32 -10
- package/dist/api/openapi.js +31 -26
- package/dist/artifacts/disk.d.ts +59 -0
- package/dist/artifacts/disk.js +563 -0
- package/dist/artifacts/export.d.ts +1 -1
- package/dist/artifacts/export.js +2 -3
- package/dist/artifacts/folders.d.ts +6 -3
- package/dist/artifacts/folders.js +17 -12
- package/dist/artifacts/service.d.ts +2 -1
- package/dist/artifacts/service.js +6 -1
- package/dist/artifacts/workspace.d.ts +1 -1
- package/dist/artifacts/workspace.js +1 -1
- package/dist/core/flow-host.d.ts +2 -3
- package/dist/core/flow-host.js +3 -0
- package/dist/core/provider.d.ts +3 -2
- package/dist/core/provider.js +5 -37
- package/dist/core/sandbox-routes.d.ts +2 -21
- package/dist/core/sandbox-routes.js +10 -43
- package/dist/execution/types.d.ts +1 -1
- package/dist/gates/contract.d.ts +3 -24
- package/dist/gates/contract.js +1 -36
- package/dist/gates/egress-credentials.d.ts +9 -0
- package/dist/gates/egress-credentials.js +11 -4
- package/dist/gates/egress.d.ts +28 -1
- package/dist/gates/egress.js +115 -10
- package/dist/gates/fixture-model.d.ts +28 -0
- package/dist/gates/fixture-model.js +92 -0
- package/dist/gates/handler.js +4 -4
- package/dist/gates/http-tool.d.ts +6 -2
- package/dist/gates/http-tool.js +3 -5
- package/dist/gates/in-process.d.ts +5 -0
- package/dist/gates/in-process.js +12 -1
- package/dist/gates/journal.d.ts +30 -0
- package/dist/gates/journal.js +52 -0
- package/dist/gates/mcp-handler.d.ts +4 -0
- package/dist/gates/mcp-handler.js +5 -1
- package/dist/gates/meter.d.ts +10 -2
- package/dist/gates/meter.js +20 -5
- package/dist/gates/policy.d.ts +49 -0
- package/dist/gates/policy.js +134 -0
- package/dist/gates/tenant-vaults.d.ts +7 -7
- package/dist/gates/tenant-vaults.js +5 -5
- package/dist/gates/tool-calls.d.ts +10 -5
- package/dist/gates/tool-calls.js +28 -10
- package/dist/gates/tool-client.d.ts +8 -0
- package/dist/gates/tool-client.js +27 -11
- package/dist/gates/tool-contract.d.ts +10 -68
- package/dist/gates/tool-contract.js +1 -85
- package/dist/gates/tool-gate.d.ts +1 -1
- package/dist/harness/calls.d.ts +12 -5
- package/dist/harness/calls.js +21 -12
- package/dist/harness/executors.js +12 -9
- package/dist/harness/main.js +18 -5
- package/dist/harness/pod.d.ts +34 -0
- package/dist/harness/pod.js +41 -0
- package/dist/harness/service.d.ts +0 -1
- package/dist/harness/service.js +13 -5
- package/dist/harness/setup.d.ts +27 -0
- package/dist/harness/setup.js +150 -0
- package/dist/harness/ws-client.js +3 -2
- package/dist/harness/ws-port.d.ts +1 -5
- package/dist/harness/ws-port.js +1 -5
- package/dist/harness-api/in-process.js +3 -3
- package/dist/harness-api/record.d.ts +15 -1
- package/dist/harness-api/record.js +174 -44
- package/dist/harness-api/redact.d.ts +3 -0
- package/dist/harness-api/redact.js +45 -0
- package/dist/harness-api/server.d.ts +8 -0
- package/dist/harness-api/server.js +93 -13
- package/dist/harness-api/start.d.ts +10 -3
- package/dist/harness-api/start.js +40 -10
- package/dist/harness-api/tool-journal.d.ts +96 -0
- package/dist/harness-api/tool-journal.js +102 -0
- package/dist/harness-api/tool-status.d.ts +13 -0
- package/dist/harness-api/tool-status.js +26 -0
- package/dist/harness-api/workspace.d.ts +6 -3
- package/dist/harness-api/workspace.js +27 -11
- package/dist/harness-api/ws-server.d.ts +11 -3
- package/dist/harness-api/ws-server.js +94 -15
- package/dist/host/gates.d.ts +2 -1
- package/dist/host/gates.js +10 -2
- package/dist/host/main.js +54 -5
- package/dist/host/operate.js +67 -5
- package/dist/host/stack-config.d.ts +64 -0
- package/dist/host/stack-config.js +61 -1
- package/dist/keys/client.js +4 -1
- package/dist/keys/keys.d.ts +5 -5
- package/dist/keys/keys.js +5 -7
- package/dist/management-openapi.json +999 -2211
- package/dist/mcp/connect.d.ts +25 -20
- package/dist/mcp/connect.js +29 -30
- package/dist/mcp/pool.d.ts +2 -2
- package/dist/mcp/pool.js +1 -1
- package/dist/mcp/preview.d.ts +3 -3
- package/dist/mcp/preview.js +10 -20
- package/dist/mcp/snapshot.d.ts +5 -11
- package/dist/mcp/snapshot.js +6 -7
- package/dist/model/pi-model.js +8 -0
- package/dist/openapi.json +6955 -2526
- package/dist/reads/types.d.ts +16 -3
- package/dist/record/append.d.ts +3 -1
- package/dist/record/append.js +1 -0
- package/dist/record/envelope.d.ts +5 -1
- package/dist/record/envelope.js +7 -3
- package/dist/record/environment.d.ts +25 -0
- package/dist/record/environment.js +44 -0
- package/dist/record/index.d.ts +1 -1
- package/dist/record/index.js +1 -1
- package/dist/sandbox/disk-fs.d.ts +95 -0
- package/dist/sandbox/disk-fs.js +206 -0
- package/dist/sandbox/join.d.ts +17 -18
- package/dist/sandbox/join.js +42 -15
- package/dist/sandbox/manager.d.ts +16 -8
- package/dist/sandbox/manager.js +33 -17
- package/dist/sandbox/placement.d.ts +13 -12
- package/dist/sandbox/placement.js +29 -12
- package/dist/sandbox/pods/client.d.ts +6 -1
- package/dist/sandbox/pods/lifecycle.d.ts +28 -27
- package/dist/sandbox/pods/lifecycle.js +14 -26
- package/dist/sandbox/pods/reconcile.js +18 -12
- package/dist/sandbox/pods/spec.d.ts +15 -13
- package/dist/sandbox/pods/spec.js +16 -20
- package/dist/sandbox/records.d.ts +2 -2
- package/dist/sandbox/records.js +3 -3
- package/dist/sandbox/resolve.d.ts +35 -27
- package/dist/sandbox/resolve.js +66 -41
- package/dist/sandbox/session-sandbox.js +1 -1
- package/dist/sandbox/setup.d.ts +61 -0
- package/dist/sandbox/setup.js +123 -0
- package/dist/sandbox/share.d.ts +11 -21
- package/dist/sandbox/share.js +12 -41
- package/dist/sandbox/tenant-config.d.ts +12 -14
- package/dist/sandbox/tenant-config.js +12 -17
- package/dist/sandbox/types.d.ts +6 -0
- package/dist/store/postgres/drizzle/0020_environments.sql +63 -0
- package/dist/store/postgres/drizzle/0021_disk_versions.sql +7 -0
- package/dist/store/postgres/drizzle/0022_model_usage_timing.sql +5 -0
- package/dist/store/postgres/drizzle/0023_artifact_pages.sql +1 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +28 -0
- package/dist/store/postgres/reads.js +117 -17
- package/dist/store/postgres/record-writer.d.ts +4 -4
- package/dist/store/postgres/record-writer.js +9 -9
- package/dist/store/postgres/record.d.ts +7 -0
- package/dist/store/postgres/record.js +23 -2
- package/dist/store/postgres/schema.d.ts +934 -761
- package/dist/store/postgres/schema.js +102 -73
- package/dist/store/postgres/store.js +119 -66
- package/dist/store/types.d.ts +109 -48
- package/dist/tenant/advance.d.ts +7 -6
- package/dist/tenant/advance.js +115 -42
- package/dist/tenant/artifact-tool.js +3 -4
- package/dist/tenant/commands.d.ts +15 -2
- package/dist/tenant/commands.js +93 -12
- package/dist/tenant/context.d.ts +48 -22
- package/dist/tenant/context.js +4 -15
- package/dist/tenant/effects.d.ts +1 -1
- package/dist/tenant/effects.js +37 -20
- package/dist/tenant/environments.d.ts +167 -0
- package/dist/tenant/environments.js +823 -0
- package/dist/tenant/harness-tokens.d.ts +21 -0
- package/dist/tenant/harness-tokens.js +61 -0
- package/dist/tenant/host-token.d.ts +1 -1
- package/dist/tenant/host-token.js +2 -4
- package/dist/tenant/identity-file.d.ts +4 -4
- package/dist/tenant/identity-file.js +17 -8
- package/dist/tenant/issuers.js +3 -3
- package/dist/tenant/principals.js +1 -1
- package/dist/tenant/reset.js +3 -3
- package/dist/tenant/runtime.d.ts +6 -1
- package/dist/tenant/runtime.js +7 -1
- package/dist/tenant/session.d.ts +3 -3
- package/dist/tenant/session.js +0 -14
- package/dist/tenant/sessions.d.ts +13 -13
- package/dist/tenant/sessions.js +61 -138
- package/dist/tenant/signing-keys.d.ts +5 -1
- package/dist/tenant/status.js +3 -3
- package/dist/tenant/sweep.js +12 -6
- package/dist/tenant/transcript.d.ts +210 -20
- package/dist/tenant/transcript.js +62 -11
- package/dist/tenant/turn-timing.d.ts +43 -0
- package/dist/tenant/turn-timing.js +39 -0
- package/dist/tenant/types.d.ts +2 -0
- package/dist/traces/ids.d.ts +42 -0
- package/dist/traces/ids.js +85 -0
- package/dist/traces/key.d.ts +6 -0
- package/dist/traces/key.js +37 -0
- package/dist/traces/map.d.ts +113 -0
- package/dist/traces/map.js +317 -0
- package/dist/traces/options.d.ts +7 -0
- package/dist/traces/options.js +1 -0
- package/dist/traces/otlp.d.ts +42 -0
- package/dist/traces/otlp.js +84 -0
- package/dist/traces/projector.d.ts +58 -0
- package/dist/traces/projector.js +200 -0
- package/dist/traces/read.d.ts +23 -0
- package/dist/traces/read.js +16 -0
- package/dist/vault/coverage.d.ts +26 -0
- package/dist/vault/coverage.js +64 -0
- package/dist/vault/error.d.ts +11 -1
- package/dist/vault/error.js +5 -1
- package/dist/vault/service.d.ts +47 -48
- package/dist/vault/service.js +321 -382
- package/dist/vault/sources.d.ts +5 -16
- package/dist/vault/sources.js +6 -8
- package/dist/version.d.ts +1 -1
- package/dist/version.js +2 -2
- package/package.json +13 -13
- package/dist/api/http/routes/sandboxes.d.ts +0 -9
- package/dist/api/http/routes/sandboxes.js +0 -153
- package/dist/api/http/routes/vaults.d.ts +0 -10
- package/dist/api/http/routes/vaults.js +0 -139
- package/dist/record/sandbox.d.ts +0 -25
- package/dist/record/sandbox.js +0 -43
- package/dist/tenant/sandboxes.d.ts +0 -123
- package/dist/tenant/sandboxes.js +0 -566
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
* Payload schemas: `@nylorun/core/contracts` (`parseTranscriptEvent`).
|
|
5
5
|
*/
|
|
6
6
|
import type { HostEffect } from "@nylorun/harness/run";
|
|
7
|
+
import type { TOOL_CALL_KINDS, TOOL_CALL_STATUSES } from "@nylorun/core/contracts";
|
|
8
|
+
export type ToolCallStatus = (typeof TOOL_CALL_STATUSES)[number];
|
|
9
|
+
export type ToolCallKind = (typeof TOOL_CALL_KINDS)[number];
|
|
7
10
|
/** The model's tool call id and the harness invocation, for tool effects. */
|
|
8
11
|
export declare function toolIds(context: unknown): {
|
|
9
12
|
callId: string;
|
|
@@ -11,7 +14,9 @@ export declare function toolIds(context: unknown): {
|
|
|
11
14
|
} | Record<string, never>;
|
|
12
15
|
/**
|
|
13
16
|
* `message.assistant` for a completed model effect: the step's text and tool calls. The
|
|
14
|
-
* provider returns a `ModelCandidate` or a bare string
|
|
17
|
+
* provider returns a `ModelCandidate` or a bare string. A step that said nothing (no text, no
|
|
18
|
+
* tool calls; a structured answer) is still one event, with `text: ""` (R7.1): every model call
|
|
19
|
+
* has its outcome row. Readers that build a conversation skip it (`isEmptyAssistantMessage`).
|
|
15
20
|
*/
|
|
16
21
|
export declare function assistantMessage(request: HostEffect, value: unknown): {
|
|
17
22
|
agent: import("@nylorun/core/define").AgentRef;
|
|
@@ -46,7 +51,8 @@ export declare function assistantMessage(request: HostEffect, value: unknown): {
|
|
|
46
51
|
} | undefined;
|
|
47
52
|
/**
|
|
48
53
|
* `context.compacted` for a model effect that summarized history (Model Calls §8): the
|
|
49
|
-
* engine replaced the older transcript with that summary.
|
|
54
|
+
* engine replaced the older transcript with that summary. A partial summary (one call of
|
|
55
|
+
* several) is marked `partial: true` (R7.1): only the last call's event replaced the history.
|
|
50
56
|
*/
|
|
51
57
|
export declare function contextCompacted(request: HostEffect, value: unknown): {
|
|
52
58
|
agent: import("@nylorun/core/define").AgentRef;
|
|
@@ -54,12 +60,14 @@ export declare function contextCompacted(request: HostEffect, value: unknown): {
|
|
|
54
60
|
trigger: "overflow" | "threshold";
|
|
55
61
|
tokensBefore: number;
|
|
56
62
|
tokensAfter: number;
|
|
63
|
+
partial?: true | undefined;
|
|
57
64
|
} | {
|
|
58
65
|
agent?: undefined;
|
|
59
66
|
invocationId?: string | undefined;
|
|
60
67
|
trigger: "overflow" | "threshold";
|
|
61
68
|
tokensBefore: number;
|
|
62
69
|
tokensAfter: number;
|
|
70
|
+
partial?: true | undefined;
|
|
63
71
|
} | undefined;
|
|
64
72
|
/** `model.failed` for a model effect that completed with a failure outcome (Model Calls §6.4). */
|
|
65
73
|
export declare function modelFailed(request: HostEffect, value: unknown): {
|
|
@@ -75,59 +83,149 @@ export declare function modelFailed(request: HostEffect, value: unknown): {
|
|
|
75
83
|
message: string;
|
|
76
84
|
retryable: boolean;
|
|
77
85
|
} | undefined;
|
|
78
|
-
/**
|
|
79
|
-
export
|
|
86
|
+
/** A gate's own start and end of a call (R7.1). */
|
|
87
|
+
export interface GateTimes {
|
|
88
|
+
readonly startedAt: string;
|
|
89
|
+
readonly endedAt: string;
|
|
90
|
+
}
|
|
91
|
+
/** What the usage ledger holds for a model call (R7.1): its `model_usage` row's columns. */
|
|
92
|
+
export interface MeteredCall {
|
|
93
|
+
readonly startedAt: string | null;
|
|
94
|
+
readonly endedAt: string | null;
|
|
95
|
+
readonly firstTokenMs: number | null;
|
|
96
|
+
readonly inputTokens: number;
|
|
97
|
+
readonly outputTokens: number;
|
|
98
|
+
readonly totalTokens: number;
|
|
99
|
+
readonly cachedTokens: number;
|
|
100
|
+
readonly costUsd: number;
|
|
101
|
+
}
|
|
102
|
+
/** From `startedAt` to `endedAt` in whole milliseconds; undefined unless both are times. */
|
|
103
|
+
export declare function durationBetween(startedAt: string | undefined, endedAt: string | undefined): number | undefined;
|
|
104
|
+
/**
|
|
105
|
+
* The timing a model call's outcome event carries (R7.1): its effect id, the journal's window
|
|
106
|
+
* (`startedAt` on the row to `settledAt`), and, when the gate metered the call (`metered`), the
|
|
107
|
+
* gate's own start and end, the first token's time and the metered usage.
|
|
108
|
+
*/
|
|
109
|
+
export declare function modelOutcomeFacts(effectId: string, window: {
|
|
110
|
+
startedAt?: string;
|
|
111
|
+
settledAt?: string;
|
|
112
|
+
}, metered: MeteredCall | undefined): {
|
|
113
|
+
effectId: string;
|
|
114
|
+
durationMs?: number | undefined;
|
|
115
|
+
gate?: {
|
|
116
|
+
startedAt: string;
|
|
117
|
+
endedAt: string;
|
|
118
|
+
} | undefined;
|
|
119
|
+
firstTokenMs?: number | undefined;
|
|
120
|
+
meteredUsage?: {
|
|
121
|
+
inputTokens: number;
|
|
122
|
+
outputTokens: number;
|
|
123
|
+
totalTokens: number;
|
|
124
|
+
cachedTokens?: number | undefined;
|
|
125
|
+
costUsd?: number | undefined;
|
|
126
|
+
} | undefined;
|
|
127
|
+
};
|
|
128
|
+
/** What the Tenant's tool policy did with a call, when it did more than allow it (R7.1). */
|
|
129
|
+
export interface ToolPolicyFact {
|
|
130
|
+
readonly decision: "ask" | "deny";
|
|
131
|
+
readonly reason: string;
|
|
132
|
+
readonly approvedBy?: string;
|
|
133
|
+
}
|
|
134
|
+
/** What the journal knows of a tool call when it ends (R5.1, R7.1), for its `tool.completed`. */
|
|
135
|
+
export interface ToolCallFacts {
|
|
136
|
+
readonly status: ToolCallStatus;
|
|
137
|
+
readonly kind?: ToolCallKind;
|
|
138
|
+
readonly server?: string;
|
|
139
|
+
readonly attempts?: number;
|
|
140
|
+
readonly durationMs?: number;
|
|
141
|
+
readonly effectId?: string;
|
|
142
|
+
readonly gate?: GateTimes;
|
|
143
|
+
readonly policy?: ToolPolicyFact;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* `tool.completed` for a tool call that ended: its output, or the tool error it reported, and
|
|
147
|
+
* how it ended (R5.1).
|
|
148
|
+
*/
|
|
149
|
+
export declare function toolCompleted(request: HostEffect, value: unknown, facts?: ToolCallFacts): {
|
|
80
150
|
agent: import("@nylorun/core/define").AgentRef;
|
|
81
151
|
error: {
|
|
82
152
|
code: string;
|
|
83
153
|
message: string;
|
|
84
154
|
server?: string | undefined;
|
|
85
|
-
vault?: string | undefined;
|
|
86
155
|
retryable?: boolean | undefined;
|
|
87
156
|
};
|
|
88
157
|
output?: undefined;
|
|
89
158
|
redacted: number;
|
|
90
159
|
capabilityId: string;
|
|
91
160
|
toolName: string;
|
|
161
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
162
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
163
|
+
server?: string | undefined;
|
|
164
|
+
attempts?: number | undefined;
|
|
165
|
+
durationMs?: number | undefined;
|
|
166
|
+
effectId?: string | undefined;
|
|
167
|
+
gate?: GateTimes | undefined;
|
|
168
|
+
policy?: ToolPolicyFact | undefined;
|
|
92
169
|
} | {
|
|
93
170
|
agent?: undefined;
|
|
94
171
|
error: {
|
|
95
172
|
code: string;
|
|
96
173
|
message: string;
|
|
97
174
|
server?: string | undefined;
|
|
98
|
-
vault?: string | undefined;
|
|
99
175
|
retryable?: boolean | undefined;
|
|
100
176
|
};
|
|
101
177
|
output?: undefined;
|
|
102
178
|
redacted: number;
|
|
103
179
|
capabilityId: string;
|
|
104
180
|
toolName: string;
|
|
181
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
182
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
183
|
+
server?: string | undefined;
|
|
184
|
+
attempts?: number | undefined;
|
|
185
|
+
durationMs?: number | undefined;
|
|
186
|
+
effectId?: string | undefined;
|
|
187
|
+
gate?: GateTimes | undefined;
|
|
188
|
+
policy?: ToolPolicyFact | undefined;
|
|
105
189
|
} | {
|
|
106
|
-
redacted?: undefined;
|
|
107
190
|
agent: import("@nylorun/core/define").AgentRef;
|
|
108
191
|
error: {
|
|
109
192
|
code: string;
|
|
110
193
|
message: string;
|
|
111
194
|
server?: string | undefined;
|
|
112
|
-
vault?: string | undefined;
|
|
113
195
|
retryable?: boolean | undefined;
|
|
114
196
|
};
|
|
115
197
|
output?: undefined;
|
|
198
|
+
redacted?: undefined;
|
|
116
199
|
capabilityId: string;
|
|
117
200
|
toolName: string;
|
|
201
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
202
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
203
|
+
server?: string | undefined;
|
|
204
|
+
attempts?: number | undefined;
|
|
205
|
+
durationMs?: number | undefined;
|
|
206
|
+
effectId?: string | undefined;
|
|
207
|
+
gate?: GateTimes | undefined;
|
|
208
|
+
policy?: ToolPolicyFact | undefined;
|
|
118
209
|
} | {
|
|
119
|
-
redacted?: undefined;
|
|
120
210
|
agent?: undefined;
|
|
121
211
|
error: {
|
|
122
212
|
code: string;
|
|
123
213
|
message: string;
|
|
124
214
|
server?: string | undefined;
|
|
125
|
-
vault?: string | undefined;
|
|
126
215
|
retryable?: boolean | undefined;
|
|
127
216
|
};
|
|
128
217
|
output?: undefined;
|
|
218
|
+
redacted?: undefined;
|
|
129
219
|
capabilityId: string;
|
|
130
220
|
toolName: string;
|
|
221
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
222
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
223
|
+
server?: string | undefined;
|
|
224
|
+
attempts?: number | undefined;
|
|
225
|
+
durationMs?: number | undefined;
|
|
226
|
+
effectId?: string | undefined;
|
|
227
|
+
gate?: GateTimes | undefined;
|
|
228
|
+
policy?: ToolPolicyFact | undefined;
|
|
131
229
|
} | {
|
|
132
230
|
agent: import("@nylorun/core/define").AgentRef;
|
|
133
231
|
error?: undefined;
|
|
@@ -135,6 +233,14 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
|
|
|
135
233
|
redacted: number;
|
|
136
234
|
capabilityId: string;
|
|
137
235
|
toolName: string;
|
|
236
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
237
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
238
|
+
server?: string | undefined;
|
|
239
|
+
attempts?: number | undefined;
|
|
240
|
+
durationMs?: number | undefined;
|
|
241
|
+
effectId?: string | undefined;
|
|
242
|
+
gate?: GateTimes | undefined;
|
|
243
|
+
policy?: ToolPolicyFact | undefined;
|
|
138
244
|
} | {
|
|
139
245
|
agent?: undefined;
|
|
140
246
|
error?: undefined;
|
|
@@ -142,20 +248,44 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
|
|
|
142
248
|
redacted: number;
|
|
143
249
|
capabilityId: string;
|
|
144
250
|
toolName: string;
|
|
251
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
252
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
253
|
+
server?: string | undefined;
|
|
254
|
+
attempts?: number | undefined;
|
|
255
|
+
durationMs?: number | undefined;
|
|
256
|
+
effectId?: string | undefined;
|
|
257
|
+
gate?: GateTimes | undefined;
|
|
258
|
+
policy?: ToolPolicyFact | undefined;
|
|
145
259
|
} | {
|
|
146
|
-
redacted?: undefined;
|
|
147
260
|
agent: import("@nylorun/core/define").AgentRef;
|
|
148
261
|
error?: undefined;
|
|
149
262
|
output: unknown;
|
|
263
|
+
redacted?: undefined;
|
|
150
264
|
capabilityId: string;
|
|
151
265
|
toolName: string;
|
|
266
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
267
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
268
|
+
server?: string | undefined;
|
|
269
|
+
attempts?: number | undefined;
|
|
270
|
+
durationMs?: number | undefined;
|
|
271
|
+
effectId?: string | undefined;
|
|
272
|
+
gate?: GateTimes | undefined;
|
|
273
|
+
policy?: ToolPolicyFact | undefined;
|
|
152
274
|
} | {
|
|
153
|
-
redacted?: undefined;
|
|
154
275
|
agent?: undefined;
|
|
155
276
|
error?: undefined;
|
|
156
277
|
output: unknown;
|
|
278
|
+
redacted?: undefined;
|
|
157
279
|
capabilityId: string;
|
|
158
280
|
toolName: string;
|
|
281
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
282
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
283
|
+
server?: string | undefined;
|
|
284
|
+
attempts?: number | undefined;
|
|
285
|
+
durationMs?: number | undefined;
|
|
286
|
+
effectId?: string | undefined;
|
|
287
|
+
gate?: GateTimes | undefined;
|
|
288
|
+
policy?: ToolPolicyFact | undefined;
|
|
159
289
|
} | {
|
|
160
290
|
callId: string;
|
|
161
291
|
invocationId: string;
|
|
@@ -164,13 +294,20 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
|
|
|
164
294
|
code: string;
|
|
165
295
|
message: string;
|
|
166
296
|
server?: string | undefined;
|
|
167
|
-
vault?: string | undefined;
|
|
168
297
|
retryable?: boolean | undefined;
|
|
169
298
|
};
|
|
170
299
|
output?: undefined;
|
|
171
300
|
redacted: number;
|
|
172
301
|
capabilityId: string;
|
|
173
302
|
toolName: string;
|
|
303
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
304
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
305
|
+
server?: string | undefined;
|
|
306
|
+
attempts?: number | undefined;
|
|
307
|
+
durationMs?: number | undefined;
|
|
308
|
+
effectId?: string | undefined;
|
|
309
|
+
gate?: GateTimes | undefined;
|
|
310
|
+
policy?: ToolPolicyFact | undefined;
|
|
174
311
|
} | {
|
|
175
312
|
callId: string;
|
|
176
313
|
invocationId: string;
|
|
@@ -179,15 +316,21 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
|
|
|
179
316
|
code: string;
|
|
180
317
|
message: string;
|
|
181
318
|
server?: string | undefined;
|
|
182
|
-
vault?: string | undefined;
|
|
183
319
|
retryable?: boolean | undefined;
|
|
184
320
|
};
|
|
185
321
|
output?: undefined;
|
|
186
322
|
redacted: number;
|
|
187
323
|
capabilityId: string;
|
|
188
324
|
toolName: string;
|
|
325
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
326
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
327
|
+
server?: string | undefined;
|
|
328
|
+
attempts?: number | undefined;
|
|
329
|
+
durationMs?: number | undefined;
|
|
330
|
+
effectId?: string | undefined;
|
|
331
|
+
gate?: GateTimes | undefined;
|
|
332
|
+
policy?: ToolPolicyFact | undefined;
|
|
189
333
|
} | {
|
|
190
|
-
redacted?: undefined;
|
|
191
334
|
callId: string;
|
|
192
335
|
invocationId: string;
|
|
193
336
|
agent: import("@nylorun/core/define").AgentRef;
|
|
@@ -195,14 +338,21 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
|
|
|
195
338
|
code: string;
|
|
196
339
|
message: string;
|
|
197
340
|
server?: string | undefined;
|
|
198
|
-
vault?: string | undefined;
|
|
199
341
|
retryable?: boolean | undefined;
|
|
200
342
|
};
|
|
201
343
|
output?: undefined;
|
|
344
|
+
redacted?: undefined;
|
|
202
345
|
capabilityId: string;
|
|
203
346
|
toolName: string;
|
|
347
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
348
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
349
|
+
server?: string | undefined;
|
|
350
|
+
attempts?: number | undefined;
|
|
351
|
+
durationMs?: number | undefined;
|
|
352
|
+
effectId?: string | undefined;
|
|
353
|
+
gate?: GateTimes | undefined;
|
|
354
|
+
policy?: ToolPolicyFact | undefined;
|
|
204
355
|
} | {
|
|
205
|
-
redacted?: undefined;
|
|
206
356
|
callId: string;
|
|
207
357
|
invocationId: string;
|
|
208
358
|
agent?: undefined;
|
|
@@ -210,12 +360,20 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
|
|
|
210
360
|
code: string;
|
|
211
361
|
message: string;
|
|
212
362
|
server?: string | undefined;
|
|
213
|
-
vault?: string | undefined;
|
|
214
363
|
retryable?: boolean | undefined;
|
|
215
364
|
};
|
|
216
365
|
output?: undefined;
|
|
366
|
+
redacted?: undefined;
|
|
217
367
|
capabilityId: string;
|
|
218
368
|
toolName: string;
|
|
369
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
370
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
371
|
+
server?: string | undefined;
|
|
372
|
+
attempts?: number | undefined;
|
|
373
|
+
durationMs?: number | undefined;
|
|
374
|
+
effectId?: string | undefined;
|
|
375
|
+
gate?: GateTimes | undefined;
|
|
376
|
+
policy?: ToolPolicyFact | undefined;
|
|
219
377
|
} | {
|
|
220
378
|
callId: string;
|
|
221
379
|
invocationId: string;
|
|
@@ -225,6 +383,14 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
|
|
|
225
383
|
redacted: number;
|
|
226
384
|
capabilityId: string;
|
|
227
385
|
toolName: string;
|
|
386
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
387
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
388
|
+
server?: string | undefined;
|
|
389
|
+
attempts?: number | undefined;
|
|
390
|
+
durationMs?: number | undefined;
|
|
391
|
+
effectId?: string | undefined;
|
|
392
|
+
gate?: GateTimes | undefined;
|
|
393
|
+
policy?: ToolPolicyFact | undefined;
|
|
228
394
|
} | {
|
|
229
395
|
callId: string;
|
|
230
396
|
invocationId: string;
|
|
@@ -234,22 +400,46 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
|
|
|
234
400
|
redacted: number;
|
|
235
401
|
capabilityId: string;
|
|
236
402
|
toolName: string;
|
|
403
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
404
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
405
|
+
server?: string | undefined;
|
|
406
|
+
attempts?: number | undefined;
|
|
407
|
+
durationMs?: number | undefined;
|
|
408
|
+
effectId?: string | undefined;
|
|
409
|
+
gate?: GateTimes | undefined;
|
|
410
|
+
policy?: ToolPolicyFact | undefined;
|
|
237
411
|
} | {
|
|
238
|
-
redacted?: undefined;
|
|
239
412
|
callId: string;
|
|
240
413
|
invocationId: string;
|
|
241
414
|
agent: import("@nylorun/core/define").AgentRef;
|
|
242
415
|
error?: undefined;
|
|
243
416
|
output: unknown;
|
|
417
|
+
redacted?: undefined;
|
|
244
418
|
capabilityId: string;
|
|
245
419
|
toolName: string;
|
|
420
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
421
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
422
|
+
server?: string | undefined;
|
|
423
|
+
attempts?: number | undefined;
|
|
424
|
+
durationMs?: number | undefined;
|
|
425
|
+
effectId?: string | undefined;
|
|
426
|
+
gate?: GateTimes | undefined;
|
|
427
|
+
policy?: ToolPolicyFact | undefined;
|
|
246
428
|
} | {
|
|
247
|
-
redacted?: undefined;
|
|
248
429
|
callId: string;
|
|
249
430
|
invocationId: string;
|
|
250
431
|
agent?: undefined;
|
|
251
432
|
error?: undefined;
|
|
252
433
|
output: unknown;
|
|
434
|
+
redacted?: undefined;
|
|
253
435
|
capabilityId: string;
|
|
254
436
|
toolName: string;
|
|
437
|
+
status?: "cancelled" | "completed" | "failed" | undefined;
|
|
438
|
+
kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
|
|
439
|
+
server?: string | undefined;
|
|
440
|
+
attempts?: number | undefined;
|
|
441
|
+
durationMs?: number | undefined;
|
|
442
|
+
effectId?: string | undefined;
|
|
443
|
+
gate?: GateTimes | undefined;
|
|
444
|
+
policy?: ToolPolicyFact | undefined;
|
|
255
445
|
} | undefined;
|
|
@@ -9,7 +9,9 @@ export function toolIds(context) {
|
|
|
9
9
|
const agentOf = (request) => request.agent ? { agent: request.agent } : {};
|
|
10
10
|
/**
|
|
11
11
|
* `message.assistant` for a completed model effect: the step's text and tool calls. The
|
|
12
|
-
* provider returns a `ModelCandidate` or a bare string
|
|
12
|
+
* provider returns a `ModelCandidate` or a bare string. A step that said nothing (no text, no
|
|
13
|
+
* tool calls; a structured answer) is still one event, with `text: ""` (R7.1): every model call
|
|
14
|
+
* has its outcome row. Readers that build a conversation skip it (`isEmptyAssistantMessage`).
|
|
13
15
|
*/
|
|
14
16
|
export function assistantMessage(request, value) {
|
|
15
17
|
const invocationId = request.context
|
|
@@ -31,8 +33,6 @@ export function assistantMessage(request, value) {
|
|
|
31
33
|
typeof block.name === "string")
|
|
32
34
|
toolCalls.push({ callId: block.id, name: block.name, input: block.args });
|
|
33
35
|
}
|
|
34
|
-
if (!text && toolCalls.length === 0)
|
|
35
|
-
return undefined;
|
|
36
36
|
const candidate = (typeof value === "object" && value !== null ? value : {});
|
|
37
37
|
const producer = candidate.evidence?.extras?.producer;
|
|
38
38
|
return {
|
|
@@ -53,11 +53,12 @@ export function assistantMessage(request, value) {
|
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
55
|
* `context.compacted` for a model effect that summarized history (Model Calls §8): the
|
|
56
|
-
* engine replaced the older transcript with that summary.
|
|
56
|
+
* engine replaced the older transcript with that summary. A partial summary (one call of
|
|
57
|
+
* several) is marked `partial: true` (R7.1): only the last call's event replaced the history.
|
|
57
58
|
*/
|
|
58
59
|
export function contextCompacted(request, value) {
|
|
59
60
|
const compaction = request.context?.compaction;
|
|
60
|
-
if (!compaction ||
|
|
61
|
+
if (!compaction || isModelFailureOutcome(value))
|
|
61
62
|
return undefined;
|
|
62
63
|
const summary = typeof value === "string"
|
|
63
64
|
? value
|
|
@@ -74,6 +75,7 @@ export function contextCompacted(request, value) {
|
|
|
74
75
|
trigger: compaction.trigger === "overflow" ? "overflow" : "threshold",
|
|
75
76
|
tokensBefore,
|
|
76
77
|
tokensAfter: keptTokens + Math.ceil(summary.trim().length / 4),
|
|
78
|
+
...(compaction.partial ? { partial: true } : {}),
|
|
77
79
|
...agentOf(request),
|
|
78
80
|
};
|
|
79
81
|
}
|
|
@@ -91,8 +93,48 @@ export function modelFailed(request, value) {
|
|
|
91
93
|
...agentOf(request),
|
|
92
94
|
};
|
|
93
95
|
}
|
|
94
|
-
/** `
|
|
95
|
-
export function
|
|
96
|
+
/** From `startedAt` to `endedAt` in whole milliseconds; undefined unless both are times. */
|
|
97
|
+
export function durationBetween(startedAt, endedAt) {
|
|
98
|
+
const started = startedAt ? Date.parse(startedAt) : NaN;
|
|
99
|
+
const ended = endedAt ? Date.parse(endedAt) : NaN;
|
|
100
|
+
if (!Number.isFinite(started) || !Number.isFinite(ended))
|
|
101
|
+
return undefined;
|
|
102
|
+
return Math.max(0, Math.round(ended - started));
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The timing a model call's outcome event carries (R7.1): its effect id, the journal's window
|
|
106
|
+
* (`startedAt` on the row to `settledAt`), and, when the gate metered the call (`metered`), the
|
|
107
|
+
* gate's own start and end, the first token's time and the metered usage.
|
|
108
|
+
*/
|
|
109
|
+
export function modelOutcomeFacts(effectId, window, metered) {
|
|
110
|
+
const durationMs = durationBetween(window.startedAt, window.settledAt);
|
|
111
|
+
return {
|
|
112
|
+
effectId,
|
|
113
|
+
...(durationMs === undefined ? {} : { durationMs }),
|
|
114
|
+
...(metered?.startedAt && metered.endedAt
|
|
115
|
+
? { gate: { startedAt: metered.startedAt, endedAt: metered.endedAt } }
|
|
116
|
+
: {}),
|
|
117
|
+
...(metered?.firstTokenMs !== null && metered?.firstTokenMs !== undefined
|
|
118
|
+
? { firstTokenMs: metered.firstTokenMs }
|
|
119
|
+
: {}),
|
|
120
|
+
...(metered
|
|
121
|
+
? {
|
|
122
|
+
meteredUsage: {
|
|
123
|
+
inputTokens: metered.inputTokens,
|
|
124
|
+
outputTokens: metered.outputTokens,
|
|
125
|
+
totalTokens: metered.totalTokens,
|
|
126
|
+
...(metered.cachedTokens > 0 ? { cachedTokens: metered.cachedTokens } : {}),
|
|
127
|
+
...(metered.costUsd > 0 ? { costUsd: metered.costUsd } : {}),
|
|
128
|
+
},
|
|
129
|
+
}
|
|
130
|
+
: {}),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* `tool.completed` for a tool call that ended: its output, or the tool error it reported, and
|
|
135
|
+
* how it ended (R5.1).
|
|
136
|
+
*/
|
|
137
|
+
export function toolCompleted(request, value, facts) {
|
|
96
138
|
const ids = toolIds(request.context);
|
|
97
139
|
if (!("callId" in ids))
|
|
98
140
|
return undefined;
|
|
@@ -102,11 +144,8 @@ export function toolCompleted(request, value) {
|
|
|
102
144
|
error: {
|
|
103
145
|
code: String(outcome.code ?? "tool.failed"),
|
|
104
146
|
message: String(outcome.message ?? ""),
|
|
105
|
-
// `credential_rejected` (R2b C1): which server
|
|
147
|
+
// `credential_rejected` (R2b C1): which server.
|
|
106
148
|
...(typeof outcome.server === "string" ? { server: outcome.server } : {}),
|
|
107
|
-
...(outcome.vault === "installation" || outcome.vault === "user"
|
|
108
|
-
? { vault: outcome.vault }
|
|
109
|
-
: {}),
|
|
110
149
|
...(typeof outcome.retryable === "boolean" ? { retryable: outcome.retryable } : {}),
|
|
111
150
|
},
|
|
112
151
|
}
|
|
@@ -121,6 +160,18 @@ export function toolCompleted(request, value) {
|
|
|
121
160
|
...ids,
|
|
122
161
|
capabilityId: request.capabilityId,
|
|
123
162
|
toolName: request.toolName,
|
|
163
|
+
...(facts
|
|
164
|
+
? {
|
|
165
|
+
status: facts.status,
|
|
166
|
+
...(facts.kind === undefined ? {} : { kind: facts.kind }),
|
|
167
|
+
...(facts.server === undefined ? {} : { server: facts.server }),
|
|
168
|
+
...(facts.attempts === undefined ? {} : { attempts: facts.attempts }),
|
|
169
|
+
...(facts.durationMs === undefined ? {} : { durationMs: facts.durationMs }),
|
|
170
|
+
...(facts.effectId === undefined ? {} : { effectId: facts.effectId }),
|
|
171
|
+
...(facts.gate === undefined ? {} : { gate: facts.gate }),
|
|
172
|
+
...(facts.policy === undefined ? {} : { policy: facts.policy }),
|
|
173
|
+
}
|
|
174
|
+
: {}),
|
|
124
175
|
...result,
|
|
125
176
|
...redacted,
|
|
126
177
|
...agentOf(request),
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A turn's timing and totals (R7.1), so the event that ends it is its span. The session body
|
|
3
|
+
* keeps when its active turn started (`turnStartedAt`, set beside `activeTurnId`), how long it
|
|
4
|
+
* has waited paused for a person (`pausedMs`), and since when it waits (`pausedAt`, while
|
|
5
|
+
* paused). `turn.completed`, `turn.failed` and `turn.cancelled` carry `endTurn`'s facts.
|
|
6
|
+
*
|
|
7
|
+
* A turn started before the Runtime recorded these has no `turnStartedAt`: its end carries no
|
|
8
|
+
* `durationMs`.
|
|
9
|
+
*/
|
|
10
|
+
import type { Tx } from "../store/types.js";
|
|
11
|
+
/** The turn timing a session body keeps. */
|
|
12
|
+
export interface TurnTiming {
|
|
13
|
+
turnStartedAt?: string;
|
|
14
|
+
/** The trace context the turn's message arrived with (R7.4); it ends with the turn. */
|
|
15
|
+
turnTrace?: unknown;
|
|
16
|
+
pausedMs?: number;
|
|
17
|
+
pausedAt?: string;
|
|
18
|
+
}
|
|
19
|
+
/** A new turn starts now. Mutates `s`. */
|
|
20
|
+
export declare function startTurn(s: TurnTiming, now?: Date): void;
|
|
21
|
+
/** The turn waits for a person from now, unless it already does. Mutates `s`. */
|
|
22
|
+
export declare function pauseTurn(s: TurnTiming, now?: Date): void;
|
|
23
|
+
/** A paused turn goes on: its wait is added to `pausedMs`. No-op when it was not paused. */
|
|
24
|
+
export declare function resumeTurn(s: TurnTiming, now?: Date): void;
|
|
25
|
+
/**
|
|
26
|
+
* The facts the event that ends turn `turnId` carries: `durationMs` from its start to now, waits
|
|
27
|
+
* included, so the turn's span holds every crossing in it; `pausedMs`, how long it waited paused
|
|
28
|
+
* (a wait still open ends now, as for a cancel); the session's agent;
|
|
29
|
+
* and the turn's totals from the usage ledger (one read, as `/v1/tenant/usage` totals a turn;
|
|
30
|
+
* `steps` are the model calls the gate metered). Clears the turn's timing from `s`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function endTurn(t: Tx, s: TurnTiming & {
|
|
33
|
+
agentId: string;
|
|
34
|
+
}, turnId: string | null, now?: Date): Promise<{
|
|
35
|
+
durationMs?: number;
|
|
36
|
+
pausedMs?: number;
|
|
37
|
+
agentId: string;
|
|
38
|
+
totals?: {
|
|
39
|
+
steps: number;
|
|
40
|
+
tokens: number;
|
|
41
|
+
costUsd: number;
|
|
42
|
+
};
|
|
43
|
+
}>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { durationBetween } from "./transcript.js";
|
|
2
|
+
/** A new turn starts now. Mutates `s`. */
|
|
3
|
+
export function startTurn(s, now = new Date()) {
|
|
4
|
+
s.turnStartedAt = now.toISOString();
|
|
5
|
+
s.pausedMs = 0;
|
|
6
|
+
delete s.pausedAt;
|
|
7
|
+
}
|
|
8
|
+
/** The turn waits for a person from now, unless it already does. Mutates `s`. */
|
|
9
|
+
export function pauseTurn(s, now = new Date()) {
|
|
10
|
+
s.pausedAt ??= now.toISOString();
|
|
11
|
+
}
|
|
12
|
+
/** A paused turn goes on: its wait is added to `pausedMs`. No-op when it was not paused. */
|
|
13
|
+
export function resumeTurn(s, now = new Date()) {
|
|
14
|
+
if (s.pausedAt === undefined)
|
|
15
|
+
return;
|
|
16
|
+
s.pausedMs = (s.pausedMs ?? 0) + (durationBetween(s.pausedAt, now.toISOString()) ?? 0);
|
|
17
|
+
delete s.pausedAt;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The facts the event that ends turn `turnId` carries: `durationMs` from its start to now, waits
|
|
21
|
+
* included, so the turn's span holds every crossing in it; `pausedMs`, how long it waited paused
|
|
22
|
+
* (a wait still open ends now, as for a cancel); the session's agent;
|
|
23
|
+
* and the turn's totals from the usage ledger (one read, as `/v1/tenant/usage` totals a turn;
|
|
24
|
+
* `steps` are the model calls the gate metered). Clears the turn's timing from `s`.
|
|
25
|
+
*/
|
|
26
|
+
export async function endTurn(t, s, turnId, now = new Date()) {
|
|
27
|
+
resumeTurn(s, now);
|
|
28
|
+
const elapsed = durationBetween(s.turnStartedAt, now.toISOString());
|
|
29
|
+
const totals = turnId ? await t.modelUsageTotals({ scope: "turn", id: turnId }) : undefined;
|
|
30
|
+
const facts = {
|
|
31
|
+
...(elapsed === undefined ? {} : { durationMs: Math.max(0, elapsed), pausedMs: s.pausedMs ?? 0 }),
|
|
32
|
+
agentId: s.agentId,
|
|
33
|
+
...(totals ? { totals: { steps: totals.calls, tokens: totals.tokens, costUsd: totals.costUsd } } : {}),
|
|
34
|
+
};
|
|
35
|
+
delete s.turnStartedAt;
|
|
36
|
+
delete s.pausedMs;
|
|
37
|
+
delete s.turnTrace;
|
|
38
|
+
return facts;
|
|
39
|
+
}
|
package/dist/tenant/types.d.ts
CHANGED
|
@@ -119,6 +119,8 @@ export interface TenantHandle {
|
|
|
119
119
|
attachHarness?(channel: HarnessChannel, peer: HarnessPeer): () => void;
|
|
120
120
|
/** The Tenant's side of a sandbox pod's join (F7.2); absent without sandbox pods. */
|
|
121
121
|
hostAuthority?(): HostAuthority | undefined;
|
|
122
|
+
/** The custom harness a per-harness token is for (R4.1), or undefined. */
|
|
123
|
+
harnessOfToken?(token: string): Promise<string | undefined>;
|
|
122
124
|
/** The Tenant's harnesses (F6.2), for `/ready`. */
|
|
123
125
|
harnessStatus?(): HarnessStatus;
|
|
124
126
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** The Tenant's trace key (`traces/key.ts`). */
|
|
2
|
+
export type TraceKey = Buffer;
|
|
3
|
+
export declare function traceIdOf(key: TraceKey, tenantId: string, sessionId: string, turnId: string): string;
|
|
4
|
+
export declare function turnSpanOf(key: TraceKey, turnId: string): string;
|
|
5
|
+
export declare function effectSpanOf(key: TraceKey, effectId: string): string;
|
|
6
|
+
export declare function egressSpanOf(key: TraceKey, sessionId: string, seq: number): string;
|
|
7
|
+
export declare function eventSpanOf(key: TraceKey, sessionId: string, seq: number): string;
|
|
8
|
+
/** W3C trace context (R7.4): `traceparent`, and `tracestate` when the caller sent one. */
|
|
9
|
+
export interface TraceContext {
|
|
10
|
+
readonly traceparent: string;
|
|
11
|
+
readonly tracestate?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A `traceparent` as W3C trace context reads it: its trace id and parent span id, or undefined
|
|
15
|
+
* when it is malformed (version `ff`, an all-zero id, or another shape), which a receiver
|
|
16
|
+
* ignores. A version above `00` may carry more fields after the flags.
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseTraceparent(value: string): {
|
|
19
|
+
traceId: string;
|
|
20
|
+
spanId: string;
|
|
21
|
+
} | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* The trace context a request's headers carry (R7.4), or undefined without a valid
|
|
24
|
+
* `traceparent`. A `tracestate` too long or with control characters is dropped, never the
|
|
25
|
+
* `traceparent`. Kept normalized: `00-<trace>-<span>-<flags>`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function traceContextOf(headers: {
|
|
28
|
+
get(name: string): string | null | undefined;
|
|
29
|
+
}): TraceContext | undefined;
|
|
30
|
+
/** `00-<trace>-<span>-01`: the context a turn or a crossing hands on (sampled). */
|
|
31
|
+
export declare function traceparentOf(traceId: string, spanId: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* The trace id of turn `turnId`: the one its message arrived with (`inbound`, R7.4), else
|
|
34
|
+
* derived. The same as `turnTraceOf` reads from the turn's `command.message`.
|
|
35
|
+
*/
|
|
36
|
+
export declare function turnTraceIdOf(key: TraceKey, ids: {
|
|
37
|
+
tenantId: string;
|
|
38
|
+
sessionId: string;
|
|
39
|
+
turnId: string;
|
|
40
|
+
}, inbound?: {
|
|
41
|
+
readonly traceparent: string;
|
|
42
|
+
}): string;
|