@opengeni/worker-bundle 1.0.0-canary.1 → 1.0.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/activities/agent-run-admission.d.ts +3 -1
- package/dist/activities/agent-turn/admission.d.ts +24 -3
- package/dist/activities/agent-turn/agent-build.d.ts +4 -0
- package/dist/activities/agent-turn/claude-usage-observer.d.ts +58 -0
- package/dist/activities/agent-turn/code-search.d.ts +60 -0
- package/dist/activities/agent-turn/codex-capacity.d.ts +13 -0
- package/dist/activities/agent-turn/codex-plan-entitlement.d.ts +105 -0
- package/dist/activities/agent-turn/codex.d.ts +3 -2
- package/dist/activities/agent-turn/compaction-prep.d.ts +21 -5
- package/dist/activities/agent-turn/credential-leases.d.ts +19 -33
- package/dist/activities/agent-turn/credential-restriction.d.ts +3 -0
- package/dist/activities/agent-turn/errors.d.ts +82 -11
- package/dist/activities/agent-turn/failure-settlement.d.ts +6 -3
- package/dist/activities/agent-turn/final-reply.d.ts +18 -0
- package/dist/activities/agent-turn/finalization-monitor.d.ts +17 -0
- package/dist/activities/agent-turn/finalization.d.ts +4 -2
- package/dist/activities/agent-turn/github-repository-bindings.d.ts +2 -0
- package/dist/activities/agent-turn/governance-model.d.ts +9 -2
- package/dist/activities/agent-turn/history-sink.d.ts +2 -0
- package/dist/activities/agent-turn/history.d.ts +2 -0
- package/dist/activities/agent-turn/input-wait-reply.d.ts +41 -0
- package/dist/activities/agent-turn/media-artifacts.d.ts +5 -3
- package/dist/activities/agent-turn/model-call-admission.d.ts +15 -0
- package/dist/activities/agent-turn/model-usage.d.ts +6 -0
- package/dist/activities/agent-turn/model-wire-dispatch.d.ts +15 -0
- package/dist/activities/agent-turn/optional-repositories.d.ts +59 -0
- package/dist/activities/agent-turn/provider-dispatch-barrier.d.ts +12 -1
- package/dist/activities/agent-turn/quiescence.d.ts +7 -7
- package/dist/activities/agent-turn/recovery-warning.d.ts +9 -0
- package/dist/activities/agent-turn/refresh-credentials.d.ts +6 -0
- package/dist/activities/agent-turn/run-credentials.d.ts +8 -3
- package/dist/activities/agent-turn/sandbox-establish.d.ts +2 -1
- package/dist/activities/agent-turn/sandbox-provision.d.ts +3 -1
- package/dist/activities/agent-turn/sandbox-route.d.ts +3 -20
- package/dist/activities/agent-turn/sandbox-runtime.d.ts +2 -2
- package/dist/activities/agent-turn/session-title.d.ts +34 -2
- package/dist/activities/agent-turn/skill-checkout.d.ts +25 -6
- package/dist/activities/agent-turn/skill-read.d.ts +70 -2
- package/dist/activities/agent-turn/skill-remove.d.ts +14 -0
- package/dist/activities/agent-turn/skill-search.d.ts +3 -1
- package/dist/activities/agent-turn/skill-tools.d.ts +15 -2
- package/dist/activities/agent-turn/skill-transfer.d.ts +18 -6
- package/dist/activities/agent-turn/stream-attempt.d.ts +7 -3
- package/dist/activities/agent-turn/subscription-lease.d.ts +38 -0
- package/dist/activities/agent-turn/tool-environment.d.ts +56 -6
- package/dist/activities/agent-turn/tool-policy.d.ts +43 -0
- package/dist/activities/agent-turn/turn-context.d.ts +29 -0
- package/dist/activities/agent-turn/turn-sandbox-access.d.ts +3 -0
- package/dist/activities/agent-turn/xai-capacity.d.ts +2 -1
- package/dist/activities/automations.d.ts +3 -1
- package/dist/activities/browser-deadline-checkpoint.d.ts +29 -0
- package/dist/activities/codemode-dispatcher.d.ts +9 -2
- package/dist/activities/codex-capacity.d.ts +18 -2
- package/dist/activities/codex-rotation.d.ts +7 -1
- package/dist/activities/context-compaction.d.ts +16 -2
- package/dist/activities/gmail-files.d.ts +32 -0
- package/dist/activities/goals.d.ts +8 -0
- package/dist/activities/knowledge-indexing.d.ts +19 -0
- package/dist/activities/mcp-account-routes.d.ts +3 -0
- package/dist/activities/mcp-credentials.d.ts +12 -13
- package/dist/activities/mcp-operation-authority.d.ts +0 -5
- package/dist/activities/model-call-fact-reconciler.d.ts +34 -0
- package/dist/activities/open-suffix-resume.d.ts +13 -0
- package/dist/activities/parent-wake.d.ts +6 -12
- package/dist/activities/retained-screenshots.d.ts +7 -2
- package/dist/activities/rig-verification.d.ts +2 -3
- package/dist/activities/run-credential-renewal.d.ts +1 -0
- package/dist/activities/run-credentials.d.ts +15 -3
- package/dist/activities/sandbox-images.d.ts +1 -1
- package/dist/activities/sandbox-lease.d.ts +47 -9
- package/dist/activities/scheduled-tasks.d.ts +4 -35
- package/dist/activities/session-state.d.ts +70 -3
- package/dist/activities/types.d.ts +55 -6
- package/dist/activities/workspace-capture.d.ts +2 -0
- package/dist/activities/workspace-credential-provider.d.ts +46 -0
- package/dist/{activities-control-HMFGSKC5.js → activities-control-BNPTRTOE.js} +1896 -418
- package/dist/activities-control-BNPTRTOE.js.map +1 -0
- package/dist/activities-control.d.ts +182 -4
- package/dist/{activities-turn-AP67JADS.js → activities-turn-5LGZOSVU.js} +4476 -1327
- package/dist/activities-turn-5LGZOSVU.js.map +1 -0
- package/dist/activities.d.ts +182 -4
- package/dist/artifact-materializer-entry.js +5 -2
- package/dist/artifact-materializer-entry.js.map +1 -1
- package/dist/artifact-outbox-entry.js +5 -2
- package/dist/artifact-outbox-entry.js.map +1 -1
- package/dist/browser-deadline-checkpoint-contract.d.ts +2 -0
- package/dist/{chunk-A4XQWVZK.js → chunk-3ZTRWDMN.js} +307 -4
- package/dist/chunk-3ZTRWDMN.js.map +1 -0
- package/dist/{chunk-RAMNYSAW.js → chunk-4ER3YXOT.js} +22 -4
- package/dist/chunk-4ER3YXOT.js.map +1 -0
- package/dist/{chunk-CYITU5UH.js → chunk-LJX7Z2KP.js} +1445 -343
- package/dist/chunk-LJX7Z2KP.js.map +1 -0
- package/dist/editable-artifact-materializer-service.d.ts +2 -2
- package/dist/editable-artifact-outbox-service.d.ts +2 -2
- package/dist/host-export-pump.d.ts +3 -1
- package/dist/host-export.d.ts +1 -1
- package/dist/host-export.js +1 -1
- package/dist/http.d.ts +1 -1
- package/dist/index.d.ts +95 -3
- package/dist/index.js +137 -43
- package/dist/index.js.map +1 -1
- package/dist/observability-metrics.d.ts +118 -8
- package/dist/retained-process-diagnostics.d.ts +4 -0
- package/dist/retained-process-retry.d.ts +7 -0
- package/dist/sandbox-resume.d.ts +55 -13
- package/dist/sandbox-routing.d.ts +5 -3
- package/dist/sandbox-snapshot-diagnostics.d.ts +20 -0
- package/dist/session-event-fanout.d.ts +6 -0
- package/dist/warm-capture-holder.d.ts +3 -0
- package/dist/worker-service-lifecycle.d.ts +12 -0
- package/dist/workflow-bundle.js +273 -41
- package/dist/workflows/activities.d.ts +1 -1
- package/dist/workflows/browser-deadline-checkpoint.d.ts +9 -0
- package/dist/workflows/scheduled-tasks.d.ts +4 -0
- package/dist/workflows/session.d.ts +36 -0
- package/dist/workflows.d.ts +1 -0
- package/package.json +21 -19
- package/src/activities/agent-run-admission.ts +17 -1
- package/src/activities/agent-turn/admission.ts +66 -3
- package/src/activities/agent-turn/agent-build.ts +84 -10
- package/src/activities/agent-turn/claim.ts +186 -43
- package/src/activities/agent-turn/claude-usage-observer.ts +221 -0
- package/src/activities/agent-turn/code-search.ts +275 -0
- package/src/activities/agent-turn/codex-capacity.ts +172 -8
- package/src/activities/agent-turn/codex-plan-entitlement.ts +254 -0
- package/src/activities/agent-turn/codex.ts +13 -5
- package/src/activities/agent-turn/compaction-prep.ts +170 -102
- package/src/activities/agent-turn/credential-leases.ts +122 -216
- package/src/activities/agent-turn/credential-restriction.ts +14 -0
- package/src/activities/agent-turn/errors.ts +647 -48
- package/src/activities/agent-turn/failure-settlement.ts +682 -130
- package/src/activities/agent-turn/final-reply.ts +46 -0
- package/src/activities/agent-turn/finalization-monitor.ts +120 -0
- package/src/activities/agent-turn/finalization.ts +146 -43
- package/src/activities/agent-turn/github-repository-bindings.ts +3 -1
- package/src/activities/agent-turn/governance-model.ts +69 -28
- package/src/activities/agent-turn/history-sink.ts +16 -2
- package/src/activities/agent-turn/history.ts +38 -11
- package/src/activities/agent-turn/input-wait-reply.ts +103 -0
- package/src/activities/agent-turn/knowledge-source-tools.ts +2 -0
- package/src/activities/agent-turn/media-artifacts.ts +2 -1
- package/src/activities/agent-turn/model-call-admission.ts +94 -0
- package/src/activities/agent-turn/model-usage.ts +64 -3
- package/src/activities/agent-turn/model-wire-dispatch.ts +27 -0
- package/src/activities/agent-turn/optional-repositories.ts +224 -0
- package/src/activities/agent-turn/provider-dispatch-barrier.ts +22 -0
- package/src/activities/agent-turn/quiescence.ts +10 -7
- package/src/activities/agent-turn/recovery-warning.ts +16 -0
- package/src/activities/agent-turn/refresh-credentials.ts +44 -0
- package/src/activities/agent-turn/run-credentials.ts +116 -55
- package/src/activities/agent-turn/run.ts +320 -93
- package/src/activities/agent-turn/sandbox-establish.ts +84 -8
- package/src/activities/agent-turn/sandbox-provision.ts +3 -1
- package/src/activities/agent-turn/sandbox-route.ts +4 -21
- package/src/activities/agent-turn/sandbox-runtime.ts +343 -18
- package/src/activities/agent-turn/session-title.ts +81 -5
- package/src/activities/agent-turn/skill-checkout.ts +111 -24
- package/src/activities/agent-turn/skill-install.ts +1 -1
- package/src/activities/agent-turn/skill-read.ts +374 -28
- package/src/activities/agent-turn/skill-remove.ts +46 -0
- package/src/activities/agent-turn/skill-save.ts +1 -1
- package/src/activities/agent-turn/skill-search.ts +10 -1
- package/src/activities/agent-turn/skill-selection.ts +4 -0
- package/src/activities/agent-turn/skill-tools.ts +112 -18
- package/src/activities/agent-turn/skill-transfer.ts +68 -23
- package/src/activities/agent-turn/stream-attempt.ts +313 -77
- package/src/activities/agent-turn/subscription-lease.ts +115 -0
- package/src/activities/agent-turn/tool-environment.ts +316 -167
- package/src/activities/agent-turn/tool-policy.ts +80 -1
- package/src/activities/agent-turn/turn-context.ts +35 -0
- package/src/activities/agent-turn/turn-sandbox-access.ts +7 -1
- package/src/activities/agent-turn/xai-capacity.ts +94 -51
- package/src/activities/automations.ts +76 -4
- package/src/activities/browser-deadline-checkpoint.ts +279 -0
- package/src/activities/capabilities.ts +108 -11
- package/src/activities/codemode-dispatcher.ts +36 -8
- package/src/activities/codex-capacity.ts +60 -25
- package/src/activities/codex-rotation.ts +39 -17
- package/src/activities/context-compaction.ts +75 -18
- package/src/activities/gmail-files.ts +88 -0
- package/src/activities/goals.ts +116 -121
- package/src/activities/google-drive-publication.ts +1 -3
- package/src/activities/image-generation-operation.ts +1 -1
- package/src/activities/knowledge-indexing.ts +269 -15
- package/src/activities/knowledge-source-sync.ts +10 -0
- package/src/activities/mcp-account-routes.ts +17 -0
- package/src/activities/mcp-credentials.ts +83 -194
- package/src/activities/mcp-operation-authority.ts +16 -41
- package/src/activities/model-call-fact-reconciler.ts +112 -0
- package/src/activities/open-suffix-resume.ts +15 -2
- package/src/activities/parent-wake.ts +46 -21
- package/src/activities/retained-screenshots.ts +82 -11
- package/src/activities/rig-verification.ts +38 -37
- package/src/activities/run-credential-renewal.ts +13 -1
- package/src/activities/run-credentials.ts +59 -17
- package/src/activities/run-input.ts +25 -16
- package/src/activities/sandbox-images.ts +0 -1
- package/src/activities/sandbox-lease.ts +798 -82
- package/src/activities/scheduled-tasks.ts +550 -178
- package/src/activities/session-state.ts +245 -6
- package/src/activities/site-auth-maintenance.ts +3 -0
- package/src/activities/types.ts +72 -5
- package/src/activities/workflow-wake.ts +2 -17
- package/src/activities/workspace-capture.ts +13 -2
- package/src/activities/workspace-credential-provider.ts +283 -0
- package/src/activities-control.ts +4 -0
- package/src/activities-turn.ts +5 -0
- package/src/activities.ts +13 -0
- package/src/activity-services.ts +16 -4
- package/src/browser-deadline-checkpoint-contract.ts +5 -0
- package/src/editable-artifact-hint-broker.ts +3 -0
- package/src/editable-artifact-materializer-service.ts +7 -3
- package/src/editable-artifact-outbox-service.ts +4 -4
- package/src/github-rest-mcp.ts +1 -2
- package/src/host-export-pump.ts +26 -4
- package/src/host-export.ts +3 -0
- package/src/http.ts +4 -2
- package/src/index.ts +99 -37
- package/src/observability-metrics.ts +510 -5
- package/src/personal-github-git-credentials.ts +2 -1
- package/src/pr-review-credentials.ts +1 -3
- package/src/retained-process-diagnostics.ts +50 -0
- package/src/retained-process-retry.ts +36 -0
- package/src/sandbox-resume.ts +388 -101
- package/src/sandbox-routing.ts +150 -25
- package/src/sandbox-snapshot-diagnostics.ts +112 -0
- package/src/session-event-fanout.ts +23 -0
- package/src/warm-capture-holder.ts +15 -0
- package/src/worker-service-lifecycle.ts +53 -0
- package/src/workflows/activities.ts +16 -1
- package/src/workflows/browser-deadline-checkpoint.ts +50 -0
- package/src/workflows/file-upload-reaper.ts +2 -0
- package/src/workflows/scheduled-tasks.ts +26 -13
- package/src/workflows/session.ts +242 -22
- package/src/workflows.ts +4 -0
- package/dist/activities/agent-turn/knowledge-sources.d.ts +0 -20
- package/dist/activities/packs.d.ts +0 -55
- package/dist/activities-control-HMFGSKC5.js.map +0 -1
- package/dist/activities-turn-AP67JADS.js.map +0 -1
- package/dist/chunk-A4XQWVZK.js.map +0 -1
- package/dist/chunk-CYITU5UH.js.map +0 -1
- package/dist/chunk-RAMNYSAW.js.map +0 -1
- package/src/activities/agent-turn/knowledge-sources.ts +0 -86
- package/src/activities/packs.ts +0 -166
|
@@ -20,10 +20,14 @@ import {
|
|
|
20
20
|
renderWorkspaceGovernanceContext,
|
|
21
21
|
type OpenGeniRuntime,
|
|
22
22
|
} from "@opengeni/runtime";
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
codeSearchDeploymentPolicy,
|
|
25
|
+
settingsWithResolvedModelContext,
|
|
26
|
+
type Settings,
|
|
27
|
+
} from "@opengeni/config";
|
|
28
|
+
import { projectReasoningConfigurations, supportsReasoningConfiguration } from "@opengeni/codex";
|
|
24
29
|
import { settingsWithSessionMcpServersForRun } from "../capabilities";
|
|
25
|
-
import { resolveRigProviderImageForRun } from "@opengeni/core";
|
|
26
|
-
import { resolveWorkspacePackRuntime, settingsWithPackSandboxImage } from "../packs";
|
|
30
|
+
import { resolveRigProviderImageForRun, settingsWithWorkspaceSandboxImage } from "@opengeni/core";
|
|
27
31
|
import { createModelHistoryAttachmentProjector } from "../run-input";
|
|
28
32
|
import type {
|
|
29
33
|
TurnActivityServices as ActivityServices,
|
|
@@ -40,12 +44,15 @@ import {
|
|
|
40
44
|
} from "../generated-images";
|
|
41
45
|
import { createTurnMediaArtifacts } from "./media-artifacts";
|
|
42
46
|
import { retryWhileMissing } from "@opengeni/storage";
|
|
47
|
+
import { measureTurnStartupPhase } from "../../observability-metrics";
|
|
43
48
|
import { WorkspaceModelPolicyBlockedError } from "@opengeni/runtime";
|
|
44
49
|
import {
|
|
45
50
|
evaluateWorkspaceModelPolicy,
|
|
46
51
|
resolveWorkspaceAgentHumanInputEnabled,
|
|
52
|
+
resolveWorkspaceDefaultAgentIdentity,
|
|
47
53
|
type MediaGenerationResult,
|
|
48
54
|
} from "@opengeni/contracts";
|
|
55
|
+
import { codeSearchEnabledForTurn } from "@opengeni/contracts/code-search";
|
|
49
56
|
|
|
50
57
|
import { assertWorkspaceHumanInputAllowed } from "./admission";
|
|
51
58
|
import {
|
|
@@ -60,6 +67,7 @@ import type { EventingState, WorkspaceRefState } from "./turn-context";
|
|
|
60
67
|
export type GovernanceModelDeps = {
|
|
61
68
|
input: RunAgentTurnInput;
|
|
62
69
|
db: ActivityServices["db"];
|
|
70
|
+
observability: ActivityServices["observability"];
|
|
63
71
|
runtime: ActivityServices["runtime"];
|
|
64
72
|
objectStorage: ActivityServices["objectStorage"];
|
|
65
73
|
eventing: EventingState;
|
|
@@ -84,13 +92,20 @@ export type GovernanceModelDeps = {
|
|
|
84
92
|
|
|
85
93
|
export type GovernanceModelOk = {
|
|
86
94
|
runtimePreparationStartedAt: number;
|
|
87
|
-
packRuntime: Awaited<ReturnType<typeof resolveWorkspacePackRuntime>>;
|
|
88
95
|
rigVersion:
|
|
89
96
|
| NonNullable<Awaited<ReturnType<typeof materializeRigVersionForAttempt>>>["version"]
|
|
90
97
|
| null;
|
|
91
98
|
rigName: string | null;
|
|
92
99
|
agentHumanInputEnabled: boolean;
|
|
100
|
+
/** Deployment and workspace allow the Jev-backed code_search tool. */
|
|
101
|
+
codeSearchEnabled: boolean;
|
|
93
102
|
workspaceAgentInstructions: string | null | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* Modular composer identity tier: the explicit workspace default identity,
|
|
105
|
+
* else the frozen legacy persona without `{{core}}`. Never dropped by
|
|
106
|
+
* instruction policies (only read for sessions with an agent configuration).
|
|
107
|
+
*/
|
|
108
|
+
workspaceAgentIdentity: string | null;
|
|
94
109
|
workspaceGovernance: ReturnType<typeof renderWorkspaceGovernanceContext>;
|
|
95
110
|
structuredWorkspacePolicyActive: boolean;
|
|
96
111
|
workspaceMemory: string | null | undefined;
|
|
@@ -155,6 +170,7 @@ export async function prepareGovernanceAndModel(
|
|
|
155
170
|
const {
|
|
156
171
|
input,
|
|
157
172
|
db,
|
|
173
|
+
observability,
|
|
158
174
|
runtime,
|
|
159
175
|
objectStorage,
|
|
160
176
|
eventing,
|
|
@@ -189,17 +205,15 @@ export async function prepareGovernanceAndModel(
|
|
|
189
205
|
attemptId: input.attemptId,
|
|
190
206
|
executionGeneration: turn.executionGeneration,
|
|
191
207
|
};
|
|
192
|
-
// Independent workspace reads after the personal-resource fence.
|
|
193
|
-
//
|
|
208
|
+
// Independent workspace reads after the personal-resource fence. The
|
|
209
|
+
// frozen rig, governance snapshots, and model policy do
|
|
194
210
|
// not depend on each other. Company-brain selection still waits on the
|
|
195
211
|
// snapshots below so its receipt stays exact.
|
|
196
212
|
const [
|
|
197
|
-
packRuntime,
|
|
198
213
|
rigMaterialization,
|
|
199
214
|
[workspace, companyProfileSnapshot, instructionPolicySnapshot, preferenceSnapshot],
|
|
200
215
|
workspaceModelPolicy,
|
|
201
216
|
] = await Promise.all([
|
|
202
|
-
resolveWorkspacePackRuntime(db, input.workspaceId),
|
|
203
217
|
session.rigId && session.rigVersionId
|
|
204
218
|
? (async () =>
|
|
205
219
|
await materializeRigVersionForAttempt(db, {
|
|
@@ -233,8 +247,20 @@ export async function prepareGovernanceAndModel(
|
|
|
233
247
|
workspaceRefs.rigVersionId = session.rigVersionId ?? "";
|
|
234
248
|
if (!workspace) throw new Error(`Workspace not found: ${input.workspaceId}`);
|
|
235
249
|
const agentHumanInputEnabled = resolveWorkspaceAgentHumanInputEnabled(workspace.settings);
|
|
250
|
+
// The session's decision was frozen when it was created, so only a
|
|
251
|
+
// deliberate switch-off (deployment or workspace Off), or undoing one,
|
|
252
|
+
// changes its tool list.
|
|
253
|
+
const codeSearchEnabled = codeSearchEnabledForTurn(
|
|
254
|
+
session.codeSearchEnabled,
|
|
255
|
+
workspace.settings,
|
|
256
|
+
codeSearchDeploymentPolicy(capabilitySettings),
|
|
257
|
+
);
|
|
236
258
|
const contextSelection = await resolveCompanyBrainContextSelection(db, governanceClaims);
|
|
237
259
|
const workspaceAgentInstructions = contextSelection.legacyWorkspaceInstructions;
|
|
260
|
+
const workspaceAgentIdentity = resolveWorkspaceDefaultAgentIdentity(
|
|
261
|
+
workspace.settings,
|
|
262
|
+
workspaceAgentInstructions,
|
|
263
|
+
).identity;
|
|
238
264
|
const memoryPromptMode = contextSelection.receipt.memoryPromptMode;
|
|
239
265
|
assertWorkspaceHumanInputAllowed(agentHumanInputEnabled, "resume", humanInputResume !== null);
|
|
240
266
|
const companyProfileIncluded = contextSelection.receipt.companyProfileIncluded;
|
|
@@ -279,15 +305,13 @@ export async function prepareGovernanceAndModel(
|
|
|
279
305
|
} catch {
|
|
280
306
|
// Contribution telemetry must never change model execution semantics.
|
|
281
307
|
}
|
|
282
|
-
// A Rig is always a setup/check layer over the deployment platform sandbox
|
|
283
|
-
//
|
|
284
|
-
const logicalSandboxSettings =
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
packRuntime.sandboxProviderImages,
|
|
290
|
-
);
|
|
308
|
+
// A Rig is always a setup/check layer over the deployment platform sandbox,
|
|
309
|
+
// or over the workspace's allowlisted selection of one.
|
|
310
|
+
const logicalSandboxSettings = settingsWithWorkspaceSandboxImage(
|
|
311
|
+
capabilitySettings,
|
|
312
|
+
workspace.settings,
|
|
313
|
+
turn.sandboxBackend,
|
|
314
|
+
);
|
|
291
315
|
const providerImageSelection = await resolveRigProviderImageForRun(
|
|
292
316
|
logicalSandboxSettings,
|
|
293
317
|
rigVersion,
|
|
@@ -299,21 +323,29 @@ export async function prepareGovernanceAndModel(
|
|
|
299
323
|
? (providerImageSelection.imageId ?? undefined)
|
|
300
324
|
: undefined;
|
|
301
325
|
const baseRunSettings = {
|
|
302
|
-
//
|
|
303
|
-
//
|
|
304
|
-
// provider-native ID is then applied only to fresh creation without
|
|
326
|
+
// A Rig uses the deployment platform base. A matching verified
|
|
327
|
+
// provider-native ID is applied only to fresh creation without
|
|
305
328
|
// changing the logical lease image.
|
|
306
329
|
...providerImageSettings,
|
|
307
330
|
openaiModel: turn.model,
|
|
308
331
|
openaiReasoningEffort: turn.reasoningEffort,
|
|
309
332
|
sandboxBackend: turn.sandboxBackend,
|
|
310
333
|
};
|
|
311
|
-
const runSettings = await
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
334
|
+
const runSettings = await measureTurnStartupPhase(
|
|
335
|
+
observability,
|
|
336
|
+
{
|
|
337
|
+
phase: "session_mcp_settings",
|
|
338
|
+
provider: turnExecutionPolicy.providerId,
|
|
339
|
+
backend: turn.sandboxBackend,
|
|
340
|
+
},
|
|
341
|
+
() =>
|
|
342
|
+
settingsWithSessionMcpServersForRun(
|
|
343
|
+
db,
|
|
344
|
+
input.workspaceId,
|
|
345
|
+
input.sessionId,
|
|
346
|
+
input.attemptId,
|
|
347
|
+
baseRunSettings,
|
|
348
|
+
),
|
|
317
349
|
);
|
|
318
350
|
|
|
319
351
|
// Multi-provider per-turn routing → the provider gating (compaction mode,
|
|
@@ -365,12 +397,20 @@ export async function prepareGovernanceAndModel(
|
|
|
365
397
|
fileIds,
|
|
366
398
|
}),
|
|
367
399
|
);
|
|
400
|
+
const useReasoningUpdates =
|
|
401
|
+
runSettings.reasoningConfigurationUpdatesEnabled &&
|
|
402
|
+
providerApi === "responses" &&
|
|
403
|
+
(resolvedModel?.provider.id === "codex" || resolvedModel?.provider.id === "openai") &&
|
|
404
|
+
supportsReasoningConfiguration(turnExecutionPolicy.upstreamModelId, turn.reasoningEffort);
|
|
368
405
|
const modelHistoryProjector = async (
|
|
369
406
|
items: Array<Record<string, unknown>>,
|
|
370
407
|
projectionOptions?: Parameters<typeof attachmentProjector>[1],
|
|
371
408
|
) =>
|
|
372
409
|
projectModelInputForCapabilities(
|
|
373
|
-
|
|
410
|
+
projectReasoningConfigurations(
|
|
411
|
+
await attachmentProjector(items, projectionOptions),
|
|
412
|
+
useReasoningUpdates,
|
|
413
|
+
),
|
|
374
414
|
modelInputPolicy,
|
|
375
415
|
);
|
|
376
416
|
const generatedImageHistoryProjector = async (
|
|
@@ -460,11 +500,12 @@ export async function prepareGovernanceAndModel(
|
|
|
460
500
|
return {
|
|
461
501
|
ok: {
|
|
462
502
|
runtimePreparationStartedAt,
|
|
463
|
-
packRuntime,
|
|
464
503
|
rigVersion,
|
|
465
504
|
rigName,
|
|
466
505
|
agentHumanInputEnabled,
|
|
506
|
+
codeSearchEnabled,
|
|
467
507
|
workspaceAgentInstructions,
|
|
508
|
+
workspaceAgentIdentity,
|
|
468
509
|
workspaceGovernance,
|
|
469
510
|
structuredWorkspacePolicyActive,
|
|
470
511
|
workspaceMemory,
|
|
@@ -50,6 +50,7 @@ export type TurnHistorySinkDeps = {
|
|
|
50
50
|
*/
|
|
51
51
|
export class TurnHistorySink {
|
|
52
52
|
private readonly prefix = new HistoryPrefixGuard();
|
|
53
|
+
private checkpointTail: Promise<void> = Promise.resolve();
|
|
53
54
|
|
|
54
55
|
seedHistory(input: string | readonly unknown[] | { readonly history: unknown[] }, count: number) {
|
|
55
56
|
const items =
|
|
@@ -76,9 +77,22 @@ export class TurnHistorySink {
|
|
|
76
77
|
|
|
77
78
|
constructor(private readonly deps: TurnHistorySinkDeps) {}
|
|
78
79
|
|
|
79
|
-
reconcileConversationTruth =
|
|
80
|
+
reconcileConversationTruth = (
|
|
80
81
|
options: { skipInputOnlyRows?: boolean; requireDurable?: boolean } = {},
|
|
81
|
-
) => {
|
|
82
|
+
): Promise<void> => {
|
|
83
|
+
// The provider loop and the stream consumer checkpoint independently.
|
|
84
|
+
// Serialize the complete read/write/acknowledgment boundary, not just the
|
|
85
|
+
// database write: each caller must read history against the latest durable
|
|
86
|
+
// watermark. Keep each caller's durability policy and rejection intact.
|
|
87
|
+
const checkpoint = this.checkpointTail.then(() => this.reconcile(options));
|
|
88
|
+
this.checkpointTail = checkpoint.catch(() => {});
|
|
89
|
+
return checkpoint;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
private reconcile = async (options: {
|
|
93
|
+
skipInputOnlyRows?: boolean;
|
|
94
|
+
requireDurable?: boolean;
|
|
95
|
+
}) => {
|
|
82
96
|
const { media } = this.deps;
|
|
83
97
|
const stream = this.deps.getStream();
|
|
84
98
|
const turnId = this.deps.getTurnId();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
normalizeProtocolJsonValue,
|
|
3
|
+
TURN_OPERATIONAL_NOTICE_PREFIX,
|
|
3
4
|
sanitizeHistoryItemsForModel,
|
|
4
5
|
toolCallIdFromSdkItem,
|
|
5
6
|
} from "@opengeni/runtime";
|
|
@@ -31,15 +32,20 @@ export function historyRowsToAppend(
|
|
|
31
32
|
}
|
|
32
33
|
// Canonical model-facing inputs (including machine-input batches) are
|
|
33
34
|
// persisted before inference and therefore live inside the prefix represented
|
|
34
|
-
// by persistedHistoryCount.
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
// positions to actual model/tool output.
|
|
35
|
+
// by persistedHistoryCount. Explicitly turn-scoped operational notices remain
|
|
36
|
+
// at their original positions: deleting them rewrites the model-visible prefix
|
|
37
|
+
// on the next turn and during compaction. Unscoped synthetic system messages
|
|
38
|
+
// still cannot silently become permanent conversation instructions.
|
|
39
39
|
const rows: Array<{ position: number; item: Record<string, unknown> }> = [];
|
|
40
40
|
for (const [offset, item] of modelReady.slice(persistedHistoryCount).entries()) {
|
|
41
41
|
if (item.type === "message" && item.role === "system") {
|
|
42
|
-
|
|
42
|
+
const content =
|
|
43
|
+
typeof item.content === "string"
|
|
44
|
+
? item.content
|
|
45
|
+
: Array.isArray(item.content)
|
|
46
|
+
? item.content.map((part: { text?: string }) => part.text ?? "").join("")
|
|
47
|
+
: "";
|
|
48
|
+
if (!content.startsWith(TURN_OPERATIONAL_NOTICE_PREFIX)) continue;
|
|
43
49
|
}
|
|
44
50
|
rows.push({
|
|
45
51
|
position: nextPosition + rows.length,
|
|
@@ -149,10 +155,18 @@ export function pendingToolCallFromSdkEvent(event: unknown): {
|
|
|
149
155
|
return null;
|
|
150
156
|
}
|
|
151
157
|
const raw = item.rawItem as Record<string, unknown>;
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
//
|
|
155
|
-
|
|
158
|
+
// Provider-executed search/image calls carry their outcome in this item,
|
|
159
|
+
// not a later function result. Registering them as pending leaves an
|
|
160
|
+
// impossible receipt behind even after the turn completes. Hosted MCP
|
|
161
|
+
// approval requests are different: they still require a response.
|
|
162
|
+
const providerData = raw.providerData as Record<string, unknown> | undefined;
|
|
163
|
+
if (
|
|
164
|
+
raw.type === "hosted_tool_call" &&
|
|
165
|
+
raw.name !== "mcp_approval_request" &&
|
|
166
|
+
providerData?.type !== "mcp_approval_request" &&
|
|
167
|
+
(raw.status === "completed" || raw.name === "image_generation_call")
|
|
168
|
+
)
|
|
169
|
+
return null;
|
|
156
170
|
const callId = toolCallIdFromSdkItem(raw) ?? raw.id;
|
|
157
171
|
const callType = raw.type;
|
|
158
172
|
if (typeof callId !== "string" || callId.length === 0 || typeof callType !== "string") {
|
|
@@ -172,7 +186,20 @@ export function toolCallProducesRetainableSessionImage(name: string | null): boo
|
|
|
172
186
|
return (
|
|
173
187
|
name === "computer_screenshot" ||
|
|
174
188
|
name === "view_image" ||
|
|
175
|
-
name === "interaction__computer_observe"
|
|
189
|
+
name === "interaction__computer_observe" ||
|
|
190
|
+
retainableBrowserScreenshotToolCall(name)
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Browser interactions can carry an image block, including opt-in observe frames. */
|
|
195
|
+
export function retainableBrowserScreenshotToolCall(name: string | null): boolean {
|
|
196
|
+
return (
|
|
197
|
+
name === "browser_screenshot" ||
|
|
198
|
+
name === "interaction__browser_screenshot" ||
|
|
199
|
+
name === "browser_observe" ||
|
|
200
|
+
name === "interaction__browser_observe" ||
|
|
201
|
+
name === "browser_act" ||
|
|
202
|
+
name === "interaction__browser_act"
|
|
176
203
|
);
|
|
177
204
|
}
|
|
178
205
|
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { listSessionEvents, type Database } from "@opengeni/db";
|
|
2
|
+
import type { TurnInitiator, TurnInitiatorContext } from "@opengeni/contracts";
|
|
3
|
+
|
|
4
|
+
type ReplyTurn = {
|
|
5
|
+
source?: string | undefined;
|
|
6
|
+
initiator: TurnInitiator;
|
|
7
|
+
initiatorContext: TurnInitiatorContext;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Provenance an agent adds when it creates a session or calls the API
|
|
12
|
+
* (`via`, `viaTruncated`), plus internal-update and legacy markers: the prompt
|
|
13
|
+
* came from an agent or a migration, not from a person.
|
|
14
|
+
*/
|
|
15
|
+
const DERIVED_PROVENANCE_KEYS = ["via", "viaTruncated", "provenanceError", "backfill"] as const;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Worker-owned producers that create a session whose first turn (`source`
|
|
19
|
+
* `user`) is their task prompt: scheduled runs, automations and site-auth
|
|
20
|
+
* maintenance. An embedding host that asserts one of these service names only
|
|
21
|
+
* gives up the recorded reply; it grants nothing.
|
|
22
|
+
*/
|
|
23
|
+
function isWorkerTaskProducer(initiator: TurnInitiator): boolean {
|
|
24
|
+
if (initiator.kind !== "service") return false;
|
|
25
|
+
const subjectId = initiator.subjectId;
|
|
26
|
+
return (
|
|
27
|
+
subjectId === "scheduler" ||
|
|
28
|
+
subjectId === "site-auth-maintenance" ||
|
|
29
|
+
subjectId.startsWith("automation:")
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Whether a turn answers a message a person sent, directly or through an API
|
|
35
|
+
* caller that relays one (an embedding host, a realtime delegation). The
|
|
36
|
+
* source alone is not enough: every session's first turn is `user`, including
|
|
37
|
+
* a child an agent spawned and a session a scheduled task created.
|
|
38
|
+
*/
|
|
39
|
+
function turnAnswersMessage(turn: ReplyTurn): boolean {
|
|
40
|
+
if (turn.source !== "user" && turn.source !== "api") return false;
|
|
41
|
+
if (
|
|
42
|
+
DERIVED_PROVENANCE_KEYS.some((key) =>
|
|
43
|
+
Object.prototype.hasOwnProperty.call(turn.initiatorContext, key),
|
|
44
|
+
)
|
|
45
|
+
) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return !isWorkerTaskProducer(turn.initiator);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The reply `turn.completed` records when a turn ends through `wait_for_input`
|
|
53
|
+
* (read back with `turnCompletedReply` in `@opengeni/contracts`).
|
|
54
|
+
*
|
|
55
|
+
* Such a turn settles with an empty `output`: the wait, not an answer, ended
|
|
56
|
+
* it. When the turn answers a person's message, its latest assistant message
|
|
57
|
+
* is still that message's answer, for example a status reply given before
|
|
58
|
+
* waiting again on work in flight. That message shares its model response with
|
|
59
|
+
* the wait call, so it streams as commentary, which is activity everywhere
|
|
60
|
+
* else. Recording it lets unread attention and Slack treat it as the answer
|
|
61
|
+
* without relabelling the provider's phase in stored history. Turns that
|
|
62
|
+
* machine input, an agent or a worker-owned producer started only narrate
|
|
63
|
+
* progress and record nothing.
|
|
64
|
+
*
|
|
65
|
+
* The message this activity completed last is the newest. An activity that
|
|
66
|
+
* resumed the turn (after an approval, a human-input answer or a recovery) and
|
|
67
|
+
* completed none reads the turn's latest durable message instead.
|
|
68
|
+
*/
|
|
69
|
+
export async function inputWaitReply(input: {
|
|
70
|
+
inputWaitYielded: boolean;
|
|
71
|
+
turn: ReplyTurn;
|
|
72
|
+
latestAssistantMessageText: string | null;
|
|
73
|
+
readLatestDurableTurnMessage: () => Promise<string | null>;
|
|
74
|
+
}): Promise<string | null> {
|
|
75
|
+
if (!input.inputWaitYielded || !turnAnswersMessage(input.turn)) return null;
|
|
76
|
+
const text = input.latestAssistantMessageText ?? (await input.readLatestDurableTurnMessage());
|
|
77
|
+
return text !== null && text.trim().length > 0 ? text : null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** How far back to look past rejected-late or duplicate completions. */
|
|
81
|
+
const DURABLE_MESSAGE_LOOKBACK = 16;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Text of the newest current `agent.message.completed` this turn persisted,
|
|
85
|
+
* or null when the session's newest completion belongs to another turn.
|
|
86
|
+
*/
|
|
87
|
+
export async function latestDurableTurnMessageText(
|
|
88
|
+
db: Database,
|
|
89
|
+
input: { workspaceId: string; sessionId: string; turnId: string },
|
|
90
|
+
): Promise<string | null> {
|
|
91
|
+
const events = await listSessionEvents(db, input.workspaceId, input.sessionId, {
|
|
92
|
+
direction: "before",
|
|
93
|
+
includeTypes: ["agent.message.completed"],
|
|
94
|
+
limit: DURABLE_MESSAGE_LOOKBACK,
|
|
95
|
+
});
|
|
96
|
+
for (const event of events.reverse()) {
|
|
97
|
+
if (event.duplicateOfEventId || (event.turnAssociation ?? "current") !== "current") continue;
|
|
98
|
+
if (event.turnId !== input.turnId) return null;
|
|
99
|
+
const text = (event.payload as { text?: unknown } | null)?.text;
|
|
100
|
+
return typeof text === "string" ? text : null;
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isRetiredNativeAtlassianSource } from "@opengeni/contracts/atlassian-native-retirement";
|
|
1
2
|
import type { AttemptToolDefinition } from "@opengeni/codemode";
|
|
2
3
|
import {
|
|
3
4
|
freezeAgentLearningPolicy,
|
|
@@ -24,6 +25,7 @@ export async function createKnowledgeSourceAttemptTools(input: {
|
|
|
24
25
|
});
|
|
25
26
|
const source = accepted?.task.agentConfig.knowledgeSource;
|
|
26
27
|
if (!accepted || !source || accepted.task.action.kind !== "agent_turn") return [];
|
|
28
|
+
if (isRetiredNativeAtlassianSource(source)) return [];
|
|
27
29
|
const actor = input.context.actor;
|
|
28
30
|
const authorize = async () => {
|
|
29
31
|
const current = await freezeAgentLearningPolicy(input.db, input.context);
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
type TurnToolCancellationFence,
|
|
13
13
|
} from "@opengeni/runtime";
|
|
14
14
|
import type { Settings } from "@opengeni/config";
|
|
15
|
-
import type { RetainedArtifactMetadata } from "@opengeni/contracts";
|
|
15
|
+
import type { RetainedArtifactMetadata, RetainedSessionScreenshotKind } from "@opengeni/contracts";
|
|
16
16
|
import type { ResumedTurnSandbox } from "../../sandbox-resume";
|
|
17
17
|
import type { SharedActivityServices } from "../types";
|
|
18
18
|
import {
|
|
@@ -79,6 +79,7 @@ export class TurnMediaArtifacts {
|
|
|
79
79
|
sandboxFileDownloadBackend: Settings["sandboxBackend"];
|
|
80
80
|
nativeImageGenerationRetention: NativeImageGenerationRetention | null = null;
|
|
81
81
|
readonly retainedSessionImageCallIds = new Set<string>();
|
|
82
|
+
readonly retainedSessionImageKindsByCallId = new Map<string, RetainedSessionScreenshotKind>();
|
|
82
83
|
|
|
83
84
|
constructor(private readonly deps: TurnMediaArtifactDeps) {
|
|
84
85
|
this.sandboxFileDownloadBackend = deps.getModelRunSettings().sandboxBackend;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { StreamEvent } from "@openai/agents";
|
|
2
|
+
|
|
3
|
+
/** SDK producer/consumer rendezvous. Usage stays on the sole consumer writer. */
|
|
4
|
+
export function createModelCallAdmission(input: {
|
|
5
|
+
signal: AbortSignal;
|
|
6
|
+
admit: () => Promise<void>;
|
|
7
|
+
}) {
|
|
8
|
+
type Receipt = {
|
|
9
|
+
promise: Promise<void>;
|
|
10
|
+
resolve: () => void;
|
|
11
|
+
reject: (error: unknown) => void;
|
|
12
|
+
};
|
|
13
|
+
const receipts = new WeakMap<object, Receipt>();
|
|
14
|
+
const responseReceipts = new Map<string, Receipt>();
|
|
15
|
+
const pending = new Set<Receipt>();
|
|
16
|
+
const responseId = (event: unknown): string | null => {
|
|
17
|
+
const id = (event as { response?: { id?: unknown } } | null)?.response?.id;
|
|
18
|
+
return typeof id === "string" && id.length > 0 ? id : null;
|
|
19
|
+
};
|
|
20
|
+
let latest: Promise<void> = Promise.resolve();
|
|
21
|
+
let failure: unknown;
|
|
22
|
+
let failed = false;
|
|
23
|
+
let rejectHalted!: (error: unknown) => void;
|
|
24
|
+
const halted = new Promise<never>((_, reject) => {
|
|
25
|
+
rejectHalted = reject;
|
|
26
|
+
});
|
|
27
|
+
void halted.catch(() => undefined);
|
|
28
|
+
const fail = (error: unknown) => {
|
|
29
|
+
if (failed) return;
|
|
30
|
+
failed = true;
|
|
31
|
+
failure = error;
|
|
32
|
+
rejectHalted(error);
|
|
33
|
+
for (const receipt of pending) receipt.reject(error);
|
|
34
|
+
pending.clear();
|
|
35
|
+
responseReceipts.clear();
|
|
36
|
+
};
|
|
37
|
+
const abort = () => fail(input.signal.reason ?? new Error("Model stream cancelled"));
|
|
38
|
+
input.signal.addEventListener("abort", abort, { once: true });
|
|
39
|
+
if (input.signal.aborted) abort();
|
|
40
|
+
return {
|
|
41
|
+
beforeModelRequest: async () => {
|
|
42
|
+
await Promise.race([latest, halted]);
|
|
43
|
+
if (failed) throw failure;
|
|
44
|
+
// Even a settled predecessor does not grant admission to the next call.
|
|
45
|
+
await Promise.race([input.admit(), halted]);
|
|
46
|
+
if (failed) throw failure;
|
|
47
|
+
},
|
|
48
|
+
onModelResponse: (event: StreamEvent): Promise<void> => {
|
|
49
|
+
if (failed) return Promise.reject(failure);
|
|
50
|
+
const id = responseId(event);
|
|
51
|
+
const existing =
|
|
52
|
+
receipts.get(event) ??
|
|
53
|
+
(id ? responseReceipts.get(id) : undefined) ??
|
|
54
|
+
(!id && pending.size === 1 ? pending.values().next().value : undefined);
|
|
55
|
+
if (existing) return existing.promise;
|
|
56
|
+
let resolve!: () => void;
|
|
57
|
+
let reject!: (error: unknown) => void;
|
|
58
|
+
const promise = new Promise<void>((yes, no) => {
|
|
59
|
+
resolve = yes;
|
|
60
|
+
reject = no;
|
|
61
|
+
});
|
|
62
|
+
// The next model entry awaits this receipt; rejection can happen sooner.
|
|
63
|
+
void promise.catch(() => undefined);
|
|
64
|
+
const receipt = { promise, resolve, reject };
|
|
65
|
+
receipts.set(event, receipt);
|
|
66
|
+
if (id) responseReceipts.set(id, receipt);
|
|
67
|
+
pending.add(receipt);
|
|
68
|
+
latest = promise;
|
|
69
|
+
return promise;
|
|
70
|
+
},
|
|
71
|
+
settle: (event: { type: string; data?: unknown }) => {
|
|
72
|
+
if (event.type !== "raw_model_stream_event" || !event.data || typeof event.data !== "object")
|
|
73
|
+
return;
|
|
74
|
+
if ((event.data as { type?: unknown }).type !== "response_done") return;
|
|
75
|
+
const id = responseId(event.data);
|
|
76
|
+
// Runner retry normalization copies response_done. It cannot create a
|
|
77
|
+
// second response before this receipt permits the next model entry.
|
|
78
|
+
const receipt =
|
|
79
|
+
receipts.get(event.data) ??
|
|
80
|
+
(id ? responseReceipts.get(id) : undefined) ??
|
|
81
|
+
(pending.size === 1 ? pending.values().next().value : undefined);
|
|
82
|
+
if (!receipt) return;
|
|
83
|
+
pending.delete(receipt);
|
|
84
|
+
if (id) responseReceipts.delete(id);
|
|
85
|
+
receipt.resolve();
|
|
86
|
+
},
|
|
87
|
+
fail,
|
|
88
|
+
close: () => {
|
|
89
|
+
input.signal.removeEventListener("abort", abort);
|
|
90
|
+
if (pending.size > 0) fail(new Error("Model stream closed before response settlement"));
|
|
91
|
+
responseReceipts.clear();
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|