@gatherthread/dsh-host 0.1.0-beta.1 → 0.1.0-beta.2
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/README.md +26 -20
- package/bundle/manifest.json +5 -5
- package/client/client.js +45 -9
- package/dist/bundle/native-plugin.js +1344 -143
- package/dist/bundle/plugin.js +1275 -121
- package/package.json +1 -1
|
@@ -729,9 +729,9 @@ function floatSafeRemainder(val, step) {
|
|
|
729
729
|
return ratio - roundedRatio;
|
|
730
730
|
}
|
|
731
731
|
var EVALUATING = /* @__PURE__ */ Symbol("evaluating");
|
|
732
|
-
function defineLazy(
|
|
732
|
+
function defineLazy(object3, key, getter) {
|
|
733
733
|
let value = void 0;
|
|
734
|
-
Object.defineProperty(
|
|
734
|
+
Object.defineProperty(object3, key, {
|
|
735
735
|
get() {
|
|
736
736
|
if (value === EVALUATING) {
|
|
737
737
|
return void 0;
|
|
@@ -743,7 +743,7 @@ function defineLazy(object2, key, getter) {
|
|
|
743
743
|
return value;
|
|
744
744
|
},
|
|
745
745
|
set(v) {
|
|
746
|
-
Object.defineProperty(
|
|
746
|
+
Object.defineProperty(object3, key, {
|
|
747
747
|
value: v
|
|
748
748
|
// configurable: true,
|
|
749
749
|
});
|
|
@@ -15810,8 +15810,8 @@ function foldObjects(members2) {
|
|
|
15810
15810
|
}
|
|
15811
15811
|
const properties = {};
|
|
15812
15812
|
const required2 = /* @__PURE__ */ new Set();
|
|
15813
|
-
for (const
|
|
15814
|
-
for (const key in
|
|
15813
|
+
for (const object3 of objects) {
|
|
15814
|
+
for (const key in object3.properties) {
|
|
15815
15815
|
if (Object.prototype.hasOwnProperty.call(properties, key))
|
|
15816
15816
|
continue;
|
|
15817
15817
|
const parts = [];
|
|
@@ -15825,18 +15825,18 @@ function foldObjects(members2) {
|
|
|
15825
15825
|
const merged = parts.length === 1 ? parts[0] : foldObjects(parts) ?? { allOf: parts };
|
|
15826
15826
|
assignProp(properties, key, merged);
|
|
15827
15827
|
}
|
|
15828
|
-
for (const key of
|
|
15828
|
+
for (const key of object3.required ?? [])
|
|
15829
15829
|
required2.add(key);
|
|
15830
15830
|
}
|
|
15831
15831
|
const folded = { type: "object", properties };
|
|
15832
15832
|
if (required2.size)
|
|
15833
15833
|
folded.required = [...required2];
|
|
15834
|
-
if (objects.every((
|
|
15834
|
+
if (objects.every((object3) => object3.additionalProperties === false)) {
|
|
15835
15835
|
folded.additionalProperties = false;
|
|
15836
15836
|
} else {
|
|
15837
15837
|
const constraints = [];
|
|
15838
|
-
for (const
|
|
15839
|
-
const constraint = undeclaredConstraint(
|
|
15838
|
+
for (const object3 of objects) {
|
|
15839
|
+
const constraint = undeclaredConstraint(object3);
|
|
15840
15840
|
if (constraint && !constraints.some((seen) => JSON.stringify(seen) === JSON.stringify(constraint)))
|
|
15841
15841
|
constraints.push(constraint);
|
|
15842
15842
|
}
|
|
@@ -19675,6 +19675,28 @@ function date4(params) {
|
|
|
19675
19675
|
return _coercedDate(ZodDate, params);
|
|
19676
19676
|
}
|
|
19677
19677
|
|
|
19678
|
+
// ../protocol/dist/src/live-output.js
|
|
19679
|
+
var utf8 = (maximum) => external_exports.string().refine((value) => new TextEncoder().encode(value).length <= maximum, "Live output is too large");
|
|
19680
|
+
var LiveOutputPayloadSchema = external_exports.object({
|
|
19681
|
+
content: utf8(24 * 1024),
|
|
19682
|
+
phase: external_exports.literal("stream"),
|
|
19683
|
+
stream_id: external_exports.string().uuid(),
|
|
19684
|
+
stream_mode: external_exports.literal("snapshot"),
|
|
19685
|
+
stream_kind: external_exports.enum(["answer", "reasoning", "tool", "plan"]),
|
|
19686
|
+
stream_revision: external_exports.number().int().min(1).max(1200),
|
|
19687
|
+
stream_state: external_exports.enum(["running", "completed", "failed"]),
|
|
19688
|
+
title: utf8(256).optional(),
|
|
19689
|
+
plan: external_exports.array(external_exports.object({ step: utf8(512), status: external_exports.enum(["pending", "in_progress", "completed"]) }).strict()).max(64).optional(),
|
|
19690
|
+
status: external_exports.enum(["thinking", "running"]).optional(),
|
|
19691
|
+
occurred_at: external_exports.string().datetime().optional(),
|
|
19692
|
+
capture_fidelity: external_exports.literal("harness_transcript").optional(),
|
|
19693
|
+
source_harness: external_exports.string().min(1).max(80).optional()
|
|
19694
|
+
}).strict().superRefine((value, context) => {
|
|
19695
|
+
if (value.stream_kind === "plan" !== (value.plan !== void 0)) {
|
|
19696
|
+
context.addIssue({ code: "custom", message: "Only plan snapshots carry plan steps" });
|
|
19697
|
+
}
|
|
19698
|
+
});
|
|
19699
|
+
|
|
19678
19700
|
// ../protocol/dist/src/code-sync.js
|
|
19679
19701
|
var CODE_SYNC_MAX_FILES = 1e3;
|
|
19680
19702
|
var CODE_SYNC_MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
@@ -19852,6 +19874,118 @@ var githubCodeSyncRequestKinds = [
|
|
|
19852
19874
|
"github_code_update"
|
|
19853
19875
|
];
|
|
19854
19876
|
|
|
19877
|
+
// ../protocol/dist/src/registration.js
|
|
19878
|
+
var RegistrationEmailSchema = external_exports.string().max(254).trim().toLowerCase().regex(/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/).refine((value) => value.split("@")[0].length <= 64 && value.split("@")[1].split(".").every((part) => part.length <= 63));
|
|
19879
|
+
var Label = external_exports.string().regex(/^[^\u0000-\u001f\u007f-\u009f]*$/u).trim().min(1).max(120);
|
|
19880
|
+
var SendRegistrationInputSchema = external_exports.object({
|
|
19881
|
+
email: RegistrationEmailSchema,
|
|
19882
|
+
challenge_token: external_exports.string().min(1).max(2048),
|
|
19883
|
+
idempotency_key: external_exports.string().uuid(),
|
|
19884
|
+
locale: external_exports.enum(["en", "zh-CN"])
|
|
19885
|
+
}).strict();
|
|
19886
|
+
var AccountPasswordSchema = external_exports.string().min(8).max(128).refine((value) => new TextEncoder().encode(value).byteLength <= 512);
|
|
19887
|
+
var EmailLoginInputSchema = external_exports.object({
|
|
19888
|
+
email: RegistrationEmailSchema,
|
|
19889
|
+
password: AccountPasswordSchema,
|
|
19890
|
+
device_name: Label,
|
|
19891
|
+
remember_device: external_exports.boolean().default(false)
|
|
19892
|
+
}).strict();
|
|
19893
|
+
var LauncherProjectId = external_exports.string().min(1).max(128).refine((value) => /^[A-Za-z0-9]/u.test(value) && !/[^A-Za-z0-9._:-]/u.test(value));
|
|
19894
|
+
var CreateCodexLauncherAuthorizationInputSchema = external_exports.object({
|
|
19895
|
+
project_id: LauncherProjectId,
|
|
19896
|
+
email: RegistrationEmailSchema
|
|
19897
|
+
}).strict();
|
|
19898
|
+
var ClaimCodexLauncherAuthorizationInputSchema = external_exports.object({
|
|
19899
|
+
authorization_id: external_exports.string().uuid().toLowerCase(),
|
|
19900
|
+
project_id: LauncherProjectId,
|
|
19901
|
+
email: RegistrationEmailSchema,
|
|
19902
|
+
password: AccountPasswordSchema,
|
|
19903
|
+
device_name: Label
|
|
19904
|
+
}).strict();
|
|
19905
|
+
var VerifyRegistrationInputSchema = external_exports.object({
|
|
19906
|
+
registration_id: external_exports.string().uuid(),
|
|
19907
|
+
code: external_exports.string().regex(/^\d{8}$/),
|
|
19908
|
+
display_name: Label,
|
|
19909
|
+
device_name: Label,
|
|
19910
|
+
remember_device: external_exports.boolean().default(false),
|
|
19911
|
+
privacy_acknowledged: external_exports.literal(true),
|
|
19912
|
+
password: AccountPasswordSchema
|
|
19913
|
+
}).strict();
|
|
19914
|
+
var RegistrationStatusSchema = external_exports.object({
|
|
19915
|
+
enabled: external_exports.boolean(),
|
|
19916
|
+
site_key: external_exports.string().nullable(),
|
|
19917
|
+
challenge_binding: external_exports.string().nullable()
|
|
19918
|
+
}).strict();
|
|
19919
|
+
var RegistrationSentSchema = external_exports.object({
|
|
19920
|
+
registration_id: external_exports.string().uuid(),
|
|
19921
|
+
expires_in_seconds: external_exports.literal(600),
|
|
19922
|
+
resend_after_seconds: external_exports.literal(60)
|
|
19923
|
+
}).strict();
|
|
19924
|
+
var PasswordResetSentSchema = external_exports.object({
|
|
19925
|
+
reset_id: external_exports.string().uuid(),
|
|
19926
|
+
expires_in_seconds: external_exports.literal(600),
|
|
19927
|
+
resend_after_seconds: external_exports.literal(60)
|
|
19928
|
+
}).strict();
|
|
19929
|
+
var VerifyPasswordResetInputSchema = external_exports.object({
|
|
19930
|
+
reset_id: external_exports.string().uuid(),
|
|
19931
|
+
email: RegistrationEmailSchema,
|
|
19932
|
+
code: external_exports.string().regex(/^\d{8}$/),
|
|
19933
|
+
password: AccountPasswordSchema,
|
|
19934
|
+
password_confirmation: AccountPasswordSchema,
|
|
19935
|
+
locale: external_exports.enum(["en", "zh-CN"])
|
|
19936
|
+
}).strict().refine((value) => value.password === value.password_confirmation);
|
|
19937
|
+
var EmailAccountSessionSchema = external_exports.object({
|
|
19938
|
+
actor: external_exports.object({ user_id: external_exports.string(), display_name: external_exports.string(), device_id: external_exports.string(), can_create_projects: external_exports.literal(true) }).strict(),
|
|
19939
|
+
expires_at: external_exports.string().datetime()
|
|
19940
|
+
}).strict();
|
|
19941
|
+
|
|
19942
|
+
// ../protocol/dist/src/cloud-api.js
|
|
19943
|
+
var CloudApiProviderIdSchema = external_exports.enum(["openai", "anthropic", "deepseek", "siliconflow-cn", "siliconflow-global", "openrouter", "qwen", "glm", "doubao"]);
|
|
19944
|
+
var CloudApiModelSchema = external_exports.string().trim().min(1).max(160).regex(/^[^\u0000-\u0020\u007f-\u009f]+$/u);
|
|
19945
|
+
var Label2 = external_exports.string().trim().min(1).max(80).regex(/^[^\u0000-\u001f\u007f-\u009f]+$/u);
|
|
19946
|
+
var CloudApiPutInputSchema = external_exports.object({
|
|
19947
|
+
expected_revision: external_exports.string().uuid().nullable(),
|
|
19948
|
+
provider_id: CloudApiProviderIdSchema,
|
|
19949
|
+
label: Label2,
|
|
19950
|
+
model: CloudApiModelSchema,
|
|
19951
|
+
enabled: external_exports.boolean(),
|
|
19952
|
+
api_key: external_exports.string().min(8).max(4096).regex(/^[\x21-\x7e]+$/u).optional()
|
|
19953
|
+
}).strict();
|
|
19954
|
+
var CloudApiDeleteInputSchema = external_exports.object({ expected_revision: external_exports.string().uuid() }).strict();
|
|
19955
|
+
var CloudApiConfigurationSchema = external_exports.object({
|
|
19956
|
+
id: external_exports.string().uuid(),
|
|
19957
|
+
revision: external_exports.string().uuid(),
|
|
19958
|
+
provider_id: CloudApiProviderIdSchema,
|
|
19959
|
+
profile_id: external_exports.string().regex(/^api-[0-9a-f-]{36}$/u),
|
|
19960
|
+
label: Label2,
|
|
19961
|
+
model: CloudApiModelSchema,
|
|
19962
|
+
enabled: external_exports.boolean(),
|
|
19963
|
+
has_key: external_exports.literal(true),
|
|
19964
|
+
updated_at: external_exports.string().datetime()
|
|
19965
|
+
}).strict();
|
|
19966
|
+
var CloudApiProviderSchema = external_exports.object({
|
|
19967
|
+
id: CloudApiProviderIdSchema,
|
|
19968
|
+
label: external_exports.string().max(80),
|
|
19969
|
+
transport: external_exports.enum(["openai-chat", "anthropic-messages"]),
|
|
19970
|
+
base_url: external_exports.string().url().max(200),
|
|
19971
|
+
docs_url: external_exports.string().url().max(300),
|
|
19972
|
+
default_model: CloudApiModelSchema.optional()
|
|
19973
|
+
}).strict();
|
|
19974
|
+
var CloudApiStatusSchema = external_exports.object({
|
|
19975
|
+
enabled: external_exports.boolean(),
|
|
19976
|
+
providers: external_exports.array(CloudApiProviderSchema).max(16),
|
|
19977
|
+
configurations: external_exports.array(CloudApiConfigurationSchema).max(8)
|
|
19978
|
+
}).strict();
|
|
19979
|
+
var CloudApiSavedSchema = external_exports.object({ configuration: CloudApiConfigurationSchema }).strict();
|
|
19980
|
+
var PersonalCloudRevisionSchema = external_exports.string().uuid().optional();
|
|
19981
|
+
function hasValidPersonalCloudRevision(value) {
|
|
19982
|
+
return value.profile_id.startsWith("api-") ? /^api-[0-9a-f-]{36}$/u.test(value.profile_id) && value.api_config_revision !== void 0 : value.api_config_revision === void 0;
|
|
19983
|
+
}
|
|
19984
|
+
var HostedAgentSelectionSchema = external_exports.object({
|
|
19985
|
+
profile_id: external_exports.string().min(1).max(64),
|
|
19986
|
+
api_config_revision: PersonalCloudRevisionSchema
|
|
19987
|
+
}).strict().refine(hasValidPersonalCloudRevision, "Personal Cloud Agent selection requires its exact revision");
|
|
19988
|
+
|
|
19855
19989
|
// ../protocol/dist/src/history-summary.js
|
|
19856
19990
|
var HISTORY_SUMMARY_MAX_SOURCE_BYTES = 20 * 1024;
|
|
19857
19991
|
var HISTORY_SUMMARY_MAX_PROMPT_BYTES = 30 * 1024;
|
|
@@ -19867,7 +20001,7 @@ function record2(value) {
|
|
|
19867
20001
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
19868
20002
|
}
|
|
19869
20003
|
function historySummaryMarker(event) {
|
|
19870
|
-
if (event.type !== "agent_request")
|
|
20004
|
+
if (event.deleted || event.type !== "agent_request")
|
|
19871
20005
|
return void 0;
|
|
19872
20006
|
const marker = record2(record2(event.payload)?.history_summary);
|
|
19873
20007
|
const ids = marker?.source_event_ids;
|
|
@@ -19897,8 +20031,10 @@ var HostedGithubTaskInputSchema = external_exports.object({
|
|
|
19897
20031
|
profile_id: external_exports.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/u),
|
|
19898
20032
|
idempotency_key: Key2,
|
|
19899
20033
|
continue_task_id: external_exports.string().regex(/^gh-task-[a-f0-9]{32}$/u).optional(),
|
|
19900
|
-
reply_to_event_id: external_exports.string().min(1).max(128).nullable().optional()
|
|
19901
|
-
|
|
20034
|
+
reply_to_event_id: external_exports.string().min(1).max(128).nullable().optional(),
|
|
20035
|
+
api_config_revision: PersonalCloudRevisionSchema,
|
|
20036
|
+
content_revision: external_exports.number().int().nonnegative().optional()
|
|
20037
|
+
}).strict().refine(hasValidPersonalCloudRevision, { message: "Personal cloud profiles require their exact configuration revision" });
|
|
19902
20038
|
var HostedGithubCompleteInputSchema = external_exports.object({
|
|
19903
20039
|
state: external_exports.string().regex(/^[A-Za-z0-9_-]{43}$/u),
|
|
19904
20040
|
code: external_exports.string().min(1).max(500)
|
|
@@ -19946,7 +20082,8 @@ var HostedGithubTaskSummarySchema = external_exports.object({
|
|
|
19946
20082
|
revision: Revision,
|
|
19947
20083
|
error_code: external_exports.string().regex(/^[a-z][a-z0-9_]{0,63}$/u).nullable(),
|
|
19948
20084
|
pull_request_url: PullUrl,
|
|
19949
|
-
expires_at: external_exports.number().int().positive().max(Number.MAX_SAFE_INTEGER)
|
|
20085
|
+
expires_at: external_exports.number().int().positive().max(Number.MAX_SAFE_INTEGER),
|
|
20086
|
+
api_config_revision: external_exports.string().uuid().optional()
|
|
19950
20087
|
}).strict();
|
|
19951
20088
|
var bytes = (value) => value.length / 4 * 3 - (value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0);
|
|
19952
20089
|
var Source = external_exports.string().max(2796204).regex(/^[A-Za-z0-9+/]*={0,2}$/u).refine((value) => value.length % 4 === 0 && bytes(value) <= 2 * 1024 * 1024).nullable();
|
|
@@ -19972,59 +20109,6 @@ var HostedGithubTaskSchema = HostedGithubTaskSummarySchema.extend({
|
|
|
19972
20109
|
});
|
|
19973
20110
|
var HostedGithubTaskListSchema = external_exports.object({ tasks: external_exports.array(HostedGithubTaskSummarySchema).max(10) }).strict();
|
|
19974
20111
|
|
|
19975
|
-
// ../protocol/dist/src/registration.js
|
|
19976
|
-
var RegistrationEmailSchema = external_exports.string().max(254).trim().toLowerCase().regex(/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/).refine((value) => value.split("@")[0].length <= 64 && value.split("@")[1].split(".").every((part) => part.length <= 63));
|
|
19977
|
-
var Label = external_exports.string().regex(/^[^\u0000-\u001f\u007f-\u009f]*$/u).trim().min(1).max(120);
|
|
19978
|
-
var SendRegistrationInputSchema = external_exports.object({
|
|
19979
|
-
email: RegistrationEmailSchema,
|
|
19980
|
-
challenge_token: external_exports.string().min(1).max(2048),
|
|
19981
|
-
idempotency_key: external_exports.string().uuid(),
|
|
19982
|
-
locale: external_exports.enum(["en", "zh-CN"])
|
|
19983
|
-
}).strict();
|
|
19984
|
-
var AccountPasswordSchema = external_exports.string().min(12).max(128).refine((value) => new TextEncoder().encode(value).byteLength <= 512);
|
|
19985
|
-
var EmailLoginInputSchema = external_exports.object({
|
|
19986
|
-
email: RegistrationEmailSchema,
|
|
19987
|
-
password: AccountPasswordSchema,
|
|
19988
|
-
device_name: Label,
|
|
19989
|
-
remember_device: external_exports.boolean().default(false)
|
|
19990
|
-
}).strict();
|
|
19991
|
-
var VerifyRegistrationInputSchema = external_exports.object({
|
|
19992
|
-
registration_id: external_exports.string().uuid(),
|
|
19993
|
-
code: external_exports.string().regex(/^\d{8}$/),
|
|
19994
|
-
display_name: Label,
|
|
19995
|
-
device_name: Label,
|
|
19996
|
-
remember_device: external_exports.boolean().default(false),
|
|
19997
|
-
privacy_acknowledged: external_exports.literal(true),
|
|
19998
|
-
password: AccountPasswordSchema
|
|
19999
|
-
}).strict();
|
|
20000
|
-
var RegistrationStatusSchema = external_exports.object({
|
|
20001
|
-
enabled: external_exports.boolean(),
|
|
20002
|
-
site_key: external_exports.string().nullable(),
|
|
20003
|
-
challenge_binding: external_exports.string().nullable()
|
|
20004
|
-
}).strict();
|
|
20005
|
-
var RegistrationSentSchema = external_exports.object({
|
|
20006
|
-
registration_id: external_exports.string().uuid(),
|
|
20007
|
-
expires_in_seconds: external_exports.literal(600),
|
|
20008
|
-
resend_after_seconds: external_exports.literal(60)
|
|
20009
|
-
}).strict();
|
|
20010
|
-
var PasswordResetSentSchema = external_exports.object({
|
|
20011
|
-
reset_id: external_exports.string().uuid(),
|
|
20012
|
-
expires_in_seconds: external_exports.literal(600),
|
|
20013
|
-
resend_after_seconds: external_exports.literal(60)
|
|
20014
|
-
}).strict();
|
|
20015
|
-
var VerifyPasswordResetInputSchema = external_exports.object({
|
|
20016
|
-
reset_id: external_exports.string().uuid(),
|
|
20017
|
-
email: RegistrationEmailSchema,
|
|
20018
|
-
code: external_exports.string().regex(/^\d{8}$/),
|
|
20019
|
-
password: AccountPasswordSchema,
|
|
20020
|
-
password_confirmation: AccountPasswordSchema,
|
|
20021
|
-
locale: external_exports.enum(["en", "zh-CN"])
|
|
20022
|
-
}).strict().refine((value) => value.password === value.password_confirmation);
|
|
20023
|
-
var EmailAccountSessionSchema = external_exports.object({
|
|
20024
|
-
actor: external_exports.object({ user_id: external_exports.string(), display_name: external_exports.string(), device_id: external_exports.string(), can_create_projects: external_exports.literal(true) }).strict(),
|
|
20025
|
-
expires_at: external_exports.string().datetime()
|
|
20026
|
-
}).strict();
|
|
20027
|
-
|
|
20028
20112
|
// ../protocol/dist/src/index.js
|
|
20029
20113
|
var sessionModes = ["solo", "multi"];
|
|
20030
20114
|
var membershipRoles = ["owner", "participant", "viewer"];
|
|
@@ -20039,7 +20123,8 @@ var eventTypes = [
|
|
|
20039
20123
|
"attachment",
|
|
20040
20124
|
"context_snapshot",
|
|
20041
20125
|
"membership_change",
|
|
20042
|
-
"session_state_change"
|
|
20126
|
+
"session_state_change",
|
|
20127
|
+
"message_deleted"
|
|
20043
20128
|
];
|
|
20044
20129
|
var eventVisibilities = ["session", "owner_only"];
|
|
20045
20130
|
var captureFidelities = [
|
|
@@ -20136,8 +20221,18 @@ var CanonicalEventSchema = external_exports.object({
|
|
|
20136
20221
|
visibility: EventVisibilitySchema,
|
|
20137
20222
|
reply_to_event_id: IdSchema.nullable(),
|
|
20138
20223
|
payload: JsonValueSchema,
|
|
20139
|
-
runtime_provenance: RuntimeProvenanceSchema.nullable()
|
|
20224
|
+
runtime_provenance: RuntimeProvenanceSchema.nullable(),
|
|
20225
|
+
content_revision: external_exports.number().int().nonnegative().optional(),
|
|
20226
|
+
deleted: external_exports.object({ deleted_at: external_exports.string().datetime(), reason: external_exports.enum(["author", "request", "summary_invalidated"]) }).strict().optional()
|
|
20140
20227
|
});
|
|
20228
|
+
var DeleteMessageInputSchema = external_exports.object({ idempotency_key: IdempotencyKeySchema }).strict();
|
|
20229
|
+
var DeleteMessageResultSchema = external_exports.object({
|
|
20230
|
+
event: CanonicalEventSchema,
|
|
20231
|
+
target_event_id: IdSchema,
|
|
20232
|
+
content_revision: external_exports.number().int().nonnegative(),
|
|
20233
|
+
affected_event_ids: external_exports.array(IdSchema).max(256),
|
|
20234
|
+
affected_truncated: external_exports.boolean()
|
|
20235
|
+
}).strict();
|
|
20141
20236
|
var MessageMentionsSchema = external_exports.array(external_exports.object({
|
|
20142
20237
|
user_id: IdSchema,
|
|
20143
20238
|
start: external_exports.number().int().nonnegative().max(1e6),
|
|
@@ -20166,6 +20261,7 @@ var AppendEventInputSchema = external_exports.object({
|
|
|
20166
20261
|
payload: JsonValueSchema,
|
|
20167
20262
|
runtime_id: IdSchema.optional(),
|
|
20168
20263
|
claim_attempt: external_exports.number().int().positive().optional(),
|
|
20264
|
+
content_revision: external_exports.number().int().nonnegative().optional(),
|
|
20169
20265
|
observed_model: external_exports.string().trim().min(1).max(160).regex(/^[^\u0000-\u001f\u007f-\u009f]+$/u).optional(),
|
|
20170
20266
|
observed_reasoning_effort: external_exports.string().trim().min(1).max(80).regex(/^[^\u0000-\u001f\u007f-\u009f]+$/u).optional()
|
|
20171
20267
|
});
|
|
@@ -20175,7 +20271,28 @@ var HostedAgentRequestInputSchema = external_exports.object({
|
|
|
20175
20271
|
include_code: external_exports.boolean().default(false),
|
|
20176
20272
|
idempotency_key: IdempotencyKeySchema,
|
|
20177
20273
|
reply_to_event_id: IdSchema.nullable().optional(),
|
|
20178
|
-
github_task_id: external_exports.string().regex(/^gh-task-[a-f0-9]{32}$/u).optional()
|
|
20274
|
+
github_task_id: external_exports.string().regex(/^gh-task-[a-f0-9]{32}$/u).optional(),
|
|
20275
|
+
continue_from_event_id: IdSchema.optional(),
|
|
20276
|
+
api_config_revision: PersonalCloudRevisionSchema,
|
|
20277
|
+
content_revision: external_exports.number().int().nonnegative().optional()
|
|
20278
|
+
}).strict().refine(hasValidPersonalCloudRevision, { message: "Personal cloud profiles require their exact configuration revision" });
|
|
20279
|
+
var HostedAgentFailurePayloadSchema = external_exports.object({
|
|
20280
|
+
content: external_exports.string().min(1).max(512),
|
|
20281
|
+
status: external_exports.literal("failed"),
|
|
20282
|
+
outcome: external_exports.enum(["timed_out", "failed"]),
|
|
20283
|
+
error: external_exports.object({
|
|
20284
|
+
code: external_exports.string().regex(/^[a-z][a-z0-9_]{0,63}$/u),
|
|
20285
|
+
provider_attempts: external_exports.number().int().min(0).max(64).optional()
|
|
20286
|
+
}).strict()
|
|
20287
|
+
}).strict();
|
|
20288
|
+
var HostedHistorySummaryInputSchema = CreateHistorySummaryInputSchema.omit({ execution_profile: true }).extend({ profile_id: HostedAgentRequestInputSchema.shape.profile_id.unwrap(), api_config_revision: PersonalCloudRevisionSchema, continue_from_event_id: IdSchema.optional() }).strict().refine(hasValidPersonalCloudRevision, { message: "Personal cloud profiles require their exact configuration revision" });
|
|
20289
|
+
var HostedAgentAcceptedSchema = external_exports.object({
|
|
20290
|
+
request_event: CanonicalEventSchema,
|
|
20291
|
+
replayed: external_exports.boolean()
|
|
20292
|
+
}).strict();
|
|
20293
|
+
var HostedAgentPausedSchema = external_exports.object({
|
|
20294
|
+
request_event_id: IdSchema,
|
|
20295
|
+
status: external_exports.literal("paused")
|
|
20179
20296
|
}).strict();
|
|
20180
20297
|
var HostedAgentStatusSchema = external_exports.discriminatedUnion("enabled", [
|
|
20181
20298
|
external_exports.object({ enabled: external_exports.literal(false) }).strict(),
|
|
@@ -20200,7 +20317,9 @@ var HostedAgentStatusSchema = external_exports.discriminatedUnion("enabled", [
|
|
|
20200
20317
|
model: external_exports.string(),
|
|
20201
20318
|
available: external_exports.boolean(),
|
|
20202
20319
|
capacity: external_exports.number().int().nonnegative(),
|
|
20203
|
-
status: external_exports.enum(["available", "busy", "daily_limit", "cooldown", "user_busy", "rate_limit"])
|
|
20320
|
+
status: external_exports.enum(["available", "busy", "daily_limit", "cooldown", "user_busy", "rate_limit"]),
|
|
20321
|
+
source: external_exports.enum(["service", "personal"]).optional(),
|
|
20322
|
+
api_config_revision: external_exports.string().uuid().optional()
|
|
20204
20323
|
}).strict()),
|
|
20205
20324
|
capabilities: external_exports.array(external_exports.string()),
|
|
20206
20325
|
privacy: external_exports.string()
|
|
@@ -20312,6 +20431,17 @@ var ClaimInvitationInputSchema = external_exports.object({
|
|
|
20312
20431
|
var AcceptInvitationInputSchema = external_exports.object({
|
|
20313
20432
|
invite_token: external_exports.string().min(32).max(512)
|
|
20314
20433
|
});
|
|
20434
|
+
var PreviewProjectInvitationInputSchema = external_exports.object({
|
|
20435
|
+
invite_token: external_exports.string().regex(/^gti_[A-Za-z0-9_-]{32,508}$/)
|
|
20436
|
+
}).strict();
|
|
20437
|
+
var ProjectInvitationPreviewSchema = external_exports.object({
|
|
20438
|
+
project: external_exports.object({ id: IdSchema, title: external_exports.string().min(1).max(200) }).strict(),
|
|
20439
|
+
inviter_display_name: external_exports.string().min(1).max(120),
|
|
20440
|
+
role: InvitationRoleSchema,
|
|
20441
|
+
created_at: external_exports.string().datetime(),
|
|
20442
|
+
expires_at: external_exports.string().datetime(),
|
|
20443
|
+
already_member: external_exports.boolean()
|
|
20444
|
+
}).strict();
|
|
20315
20445
|
var InvitationRecordSchema = external_exports.object({
|
|
20316
20446
|
id: IdSchema,
|
|
20317
20447
|
session_id: IdSchema,
|
|
@@ -20386,6 +20516,10 @@ var DeviceAuthorizationRecordSchema = external_exports.object({
|
|
|
20386
20516
|
claimed_at: external_exports.string().datetime().nullable(),
|
|
20387
20517
|
claimed_by_device_id: IdSchema.nullable()
|
|
20388
20518
|
});
|
|
20519
|
+
var CodexLauncherAuthorizationSchema = external_exports.object({
|
|
20520
|
+
authorization: DeviceAuthorizationRecordSchema.strict(),
|
|
20521
|
+
email: RegistrationEmailSchema
|
|
20522
|
+
}).strict();
|
|
20389
20523
|
var RotateDeviceTokenInputSchema = external_exports.object({
|
|
20390
20524
|
expires_at: external_exports.string().datetime().nullable().optional()
|
|
20391
20525
|
});
|
|
@@ -20420,6 +20554,7 @@ var RegisterRuntimeInputSchema = external_exports.object({
|
|
|
20420
20554
|
provider: external_exports.string().trim().min(1).max(80),
|
|
20421
20555
|
model: external_exports.string().trim().min(1).max(160),
|
|
20422
20556
|
execution_profiles: RuntimeExecutionProfilesSchema.optional(),
|
|
20557
|
+
context_deletion_version: external_exports.literal(1).optional(),
|
|
20423
20558
|
local_session_id: external_exports.string().trim().min(1).max(512),
|
|
20424
20559
|
capture_fidelity: CaptureFidelitySchema
|
|
20425
20560
|
});
|
|
@@ -20433,11 +20568,13 @@ var AgentRequestClaimSchema = external_exports.object({
|
|
|
20433
20568
|
// `paused` is a decision by the requester, not a claim a runtime can execute.
|
|
20434
20569
|
// It is reported so a connector can skip the request without advancing past it.
|
|
20435
20570
|
status: external_exports.enum(["claimed", "completed", "paused"]),
|
|
20436
|
-
attempt_count: external_exports.number().int().positive().optional()
|
|
20571
|
+
attempt_count: external_exports.number().int().positive().optional(),
|
|
20572
|
+
content_revision: external_exports.number().int().nonnegative().optional()
|
|
20437
20573
|
}).strict();
|
|
20438
20574
|
var CompleteAgentRequestInputSchema = external_exports.object({
|
|
20439
20575
|
runtime_id: IdSchema,
|
|
20440
20576
|
claim_attempt: external_exports.number().int().positive().optional(),
|
|
20577
|
+
content_revision: external_exports.number().int().nonnegative().optional(),
|
|
20441
20578
|
idempotency_key: IdempotencyKeySchema,
|
|
20442
20579
|
payload: JsonValueSchema,
|
|
20443
20580
|
observed_model: external_exports.string().trim().min(1).max(160).regex(/^[^\u0000-\u001f\u007f-\u009f]+$/u).optional(),
|
|
@@ -20452,6 +20589,7 @@ var CommitLocalTurnInputSchema = external_exports.object({
|
|
|
20452
20589
|
local_turn_id: IdSchema,
|
|
20453
20590
|
runtime_id: IdSchema,
|
|
20454
20591
|
based_on_sequence: external_exports.number().int().nonnegative(),
|
|
20592
|
+
content_revision: external_exports.number().int().nonnegative().optional(),
|
|
20455
20593
|
occurred_at: external_exports.string().datetime(),
|
|
20456
20594
|
observed_model: external_exports.string().trim().min(1).max(160).regex(/^[^\u0000-\u001f\u007f-\u009f]+$/u).optional(),
|
|
20457
20595
|
observed_reasoning_effort: external_exports.string().trim().min(1).max(80).regex(/^[^\u0000-\u001f\u007f-\u009f]+$/u).optional(),
|
|
@@ -20505,6 +20643,7 @@ var SnapshotRequestRecordSchema = external_exports.object({
|
|
|
20505
20643
|
kind: SnapshotRequestKindSchema,
|
|
20506
20644
|
through_sequence: external_exports.number().int().nonnegative(),
|
|
20507
20645
|
status: SnapshotRequestStatusSchema,
|
|
20646
|
+
content_revision: external_exports.number().int().nonnegative().optional(),
|
|
20508
20647
|
target_runtime_id: IdSchema.nullable(),
|
|
20509
20648
|
claimed_by_runtime_id: IdSchema.nullable(),
|
|
20510
20649
|
created_at: external_exports.string().datetime(),
|
|
@@ -20530,7 +20669,8 @@ var SubscribeMessageSchema = external_exports.object({
|
|
|
20530
20669
|
var ReplayResponseSchema = external_exports.object({
|
|
20531
20670
|
events: external_exports.array(CanonicalEventSchema),
|
|
20532
20671
|
cursor: external_exports.number().int().nonnegative(),
|
|
20533
|
-
has_more: external_exports.boolean()
|
|
20672
|
+
has_more: external_exports.boolean(),
|
|
20673
|
+
content_revision: external_exports.number().int().nonnegative().optional()
|
|
20534
20674
|
});
|
|
20535
20675
|
var SessionListItemSchema = external_exports.object({
|
|
20536
20676
|
id: IdSchema,
|
|
@@ -20541,6 +20681,7 @@ var SessionListItemSchema = external_exports.object({
|
|
|
20541
20681
|
state: external_exports.enum(["active", "archived"]),
|
|
20542
20682
|
role: MembershipRoleSchema,
|
|
20543
20683
|
current_sequence: external_exports.number().int().nonnegative(),
|
|
20684
|
+
content_revision: external_exports.number().int().nonnegative().optional(),
|
|
20544
20685
|
member_count: external_exports.number().int().nonnegative().optional(),
|
|
20545
20686
|
updated_at: external_exports.string().datetime()
|
|
20546
20687
|
});
|
|
@@ -20644,7 +20785,8 @@ var HttpCollaborationClient = class {
|
|
|
20644
20785
|
return {
|
|
20645
20786
|
events,
|
|
20646
20787
|
nextSequence: requiredNumber(body.cursor, "cursor"),
|
|
20647
|
-
hasMore: body.has_more === true
|
|
20788
|
+
hasMore: body.has_more === true,
|
|
20789
|
+
...body.content_revision === void 0 ? {} : { contentRevision: requiredRevision(body.content_revision, "events.content_revision") }
|
|
20648
20790
|
};
|
|
20649
20791
|
}
|
|
20650
20792
|
async readContext(sessionId, view, throughSequence) {
|
|
@@ -20702,7 +20844,8 @@ var HttpCollaborationClient = class {
|
|
|
20702
20844
|
status,
|
|
20703
20845
|
requestId: requiredString(body.request_event_id, "claim.request_event_id"),
|
|
20704
20846
|
runtimeId: requiredString(body.runtime_id, "claim.runtime_id"),
|
|
20705
|
-
attemptCount
|
|
20847
|
+
attemptCount,
|
|
20848
|
+
...body.content_revision === void 0 ? {} : { contentRevision: requiredRevision(body.content_revision, "claim.content_revision") }
|
|
20706
20849
|
};
|
|
20707
20850
|
}
|
|
20708
20851
|
async completeAgentRequest(sessionId, requestId, input2) {
|
|
@@ -20711,6 +20854,7 @@ var HttpCollaborationClient = class {
|
|
|
20711
20854
|
body: JSON.stringify({
|
|
20712
20855
|
runtime_id: input2.runtimeId,
|
|
20713
20856
|
...input2.claimAttempt === void 0 ? {} : { claim_attempt: input2.claimAttempt },
|
|
20857
|
+
...input2.contentRevision === void 0 ? {} : { content_revision: input2.contentRevision },
|
|
20714
20858
|
idempotency_key: input2.idempotencyKey,
|
|
20715
20859
|
payload: truncateJsonValue(input2.payload, 160 * 1024),
|
|
20716
20860
|
...input2.observedModel === void 0 ? {} : { observed_model: input2.observedModel },
|
|
@@ -20725,6 +20869,7 @@ var HttpCollaborationClient = class {
|
|
|
20725
20869
|
body: JSON.stringify({
|
|
20726
20870
|
runtime_id: input2.runtimeId,
|
|
20727
20871
|
...input2.claimAttempt === void 0 ? {} : { claim_attempt: input2.claimAttempt },
|
|
20872
|
+
...input2.contentRevision === void 0 ? {} : { content_revision: input2.contentRevision },
|
|
20728
20873
|
idempotency_key: input2.idempotencyKey,
|
|
20729
20874
|
payload: truncateJsonValue(input2.payload, 32 * 1024),
|
|
20730
20875
|
...input2.observedModel === void 0 ? {} : { observed_model: input2.observedModel },
|
|
@@ -20741,6 +20886,7 @@ var HttpCollaborationClient = class {
|
|
|
20741
20886
|
local_turn_id: input2.localTurnId,
|
|
20742
20887
|
runtime_id: input2.runtimeId,
|
|
20743
20888
|
based_on_sequence: input2.basedOnSequence,
|
|
20889
|
+
...input2.contentRevision === void 0 ? {} : { content_revision: input2.contentRevision },
|
|
20744
20890
|
occurred_at: input2.occurredAt,
|
|
20745
20891
|
...input2.observedModel === void 0 ? {} : { observed_model: input2.observedModel },
|
|
20746
20892
|
...input2.observedReasoningEffort === void 0 ? {} : { observed_reasoning_effort: input2.observedReasoningEffort },
|
|
@@ -20847,6 +20993,7 @@ function toWireEvent(event) {
|
|
|
20847
20993
|
visibility: event.visibility ?? "session",
|
|
20848
20994
|
runtime_id: event.runtimeId ?? event.runtime?.runtimeId,
|
|
20849
20995
|
claim_attempt: event.claimAttempt,
|
|
20996
|
+
...event.contentRevision === void 0 ? {} : { content_revision: event.contentRevision },
|
|
20850
20997
|
observed_model: event.observedModel,
|
|
20851
20998
|
observed_reasoning_effort: event.observedReasoningEffort
|
|
20852
20999
|
};
|
|
@@ -20872,7 +21019,8 @@ function toWireRuntimeRegistration(runtime) {
|
|
|
20872
21019
|
local_session_id: runtime.localSessionId,
|
|
20873
21020
|
capture_fidelity: runtime.captureFidelity,
|
|
20874
21021
|
...runtime.capabilities === void 0 ? {} : { capabilities: [...runtime.capabilities] },
|
|
20875
|
-
...runtime.purpose === void 0 ? {} : { purpose: runtime.purpose }
|
|
21022
|
+
...runtime.purpose === void 0 ? {} : { purpose: runtime.purpose },
|
|
21023
|
+
...runtime.contextDeletionVersion === void 0 ? {} : { context_deletion_version: runtime.contextDeletionVersion }
|
|
20876
21024
|
};
|
|
20877
21025
|
}
|
|
20878
21026
|
function validateContextReadInput(sessionId, view, throughSequence) {
|
|
@@ -20933,7 +21081,17 @@ function parseHistoryContext(value, expectedView, throughSequence) {
|
|
|
20933
21081
|
if (items.some((item) => sourceIds.has(item.event_id))) {
|
|
20934
21082
|
throw new Error("Collaboration API context repeats summarized sources");
|
|
20935
21083
|
}
|
|
20936
|
-
return {
|
|
21084
|
+
return {
|
|
21085
|
+
view: value.view,
|
|
21086
|
+
through_sequence: Number(value.through_sequence),
|
|
21087
|
+
items,
|
|
21088
|
+
...value.content_revision === void 0 ? {} : { content_revision: requiredRevision(value.content_revision, "context.content_revision") }
|
|
21089
|
+
};
|
|
21090
|
+
}
|
|
21091
|
+
function requiredRevision(value, label) {
|
|
21092
|
+
if (!Number.isSafeInteger(value) || Number(value) < 0)
|
|
21093
|
+
throw new Error(`Collaboration API returned invalid ${label}`);
|
|
21094
|
+
return Number(value);
|
|
20937
21095
|
}
|
|
20938
21096
|
function isContextId(value) {
|
|
20939
21097
|
return typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(value);
|
|
@@ -20952,9 +21110,17 @@ function fromWireEvent(value) {
|
|
|
20952
21110
|
...typeof input2.reply_to_event_id === "string" ? { replyTo: input2.reply_to_event_id } : {},
|
|
20953
21111
|
timestamp: requiredString(input2.created_at, "event.created_at"),
|
|
20954
21112
|
payload: input2.payload,
|
|
21113
|
+
...input2.content_revision === void 0 ? {} : { contentRevision: requiredRevision(input2.content_revision, "event.content_revision") },
|
|
21114
|
+
...input2.deleted === void 0 ? {} : { deleted: fromWireDeletion(input2.deleted) },
|
|
20955
21115
|
...runtime === void 0 ? {} : { runtime }
|
|
20956
21116
|
};
|
|
20957
21117
|
}
|
|
21118
|
+
function fromWireDeletion(value) {
|
|
21119
|
+
const input2 = requiredObject(value);
|
|
21120
|
+
if (input2.reason !== "author" && input2.reason !== "request" && input2.reason !== "summary_invalidated")
|
|
21121
|
+
throw new Error("Collaboration API returned invalid event.deleted reason");
|
|
21122
|
+
return { deletedAt: requiredString(input2.deleted_at, "event.deleted.deleted_at"), reason: input2.reason };
|
|
21123
|
+
}
|
|
20958
21124
|
function fromWireSnapshotRequest(value) {
|
|
20959
21125
|
const input2 = requiredObject(value);
|
|
20960
21126
|
const status = requiredString(input2.status, "snapshot_request.status");
|
|
@@ -20990,6 +21156,7 @@ function fromWireSnapshotRequest(value) {
|
|
|
20990
21156
|
kind,
|
|
20991
21157
|
...typeof input2.target_runtime_id === "string" ? { targetRuntimeId: input2.target_runtime_id } : {},
|
|
20992
21158
|
throughSequence: requiredNumber(input2.through_sequence, "snapshot_request.through_sequence"),
|
|
21159
|
+
...input2.content_revision === void 0 ? {} : { contentRevision: requiredRevision(input2.content_revision, "snapshot_request.content_revision") },
|
|
20993
21160
|
status,
|
|
20994
21161
|
...createdAt === void 0 ? {} : { createdAt },
|
|
20995
21162
|
..."result" in input2 ? { result: input2.result } : {},
|
|
@@ -21009,7 +21176,8 @@ function fromWireSession(value) {
|
|
|
21009
21176
|
...input2.state === "active" || input2.state === "archived" ? { state: input2.state } : {},
|
|
21010
21177
|
...name2 === void 0 ? {} : { name: name2 },
|
|
21011
21178
|
...role === void 0 ? {} : { role },
|
|
21012
|
-
...latestSequence === void 0 ? {} : { latestSequence }
|
|
21179
|
+
...latestSequence === void 0 ? {} : { latestSequence },
|
|
21180
|
+
...input2.content_revision === void 0 ? {} : { contentRevision: requiredRevision(input2.content_revision, "session.content_revision") }
|
|
21013
21181
|
};
|
|
21014
21182
|
}
|
|
21015
21183
|
function fromWireProject(value) {
|
|
@@ -21056,7 +21224,8 @@ function fromWireRuntime(value) {
|
|
|
21056
21224
|
...input2.execution_profiles === void 0 || input2.execution_profiles === null ? {} : { executionProfiles: fromWireExecutionProfiles(input2.execution_profiles) },
|
|
21057
21225
|
localSessionId: requiredString(input2.local_session_id, "runtime.local_session_id"),
|
|
21058
21226
|
captureFidelity: requiredString(input2.capture_fidelity, "runtime.capture_fidelity"),
|
|
21059
|
-
purpose
|
|
21227
|
+
purpose,
|
|
21228
|
+
...input2.context_deletion_version === 1 ? { contextDeletionVersion: 1 } : {}
|
|
21060
21229
|
};
|
|
21061
21230
|
}
|
|
21062
21231
|
function fromWireExecutionProfiles(value) {
|
|
@@ -21187,8 +21356,8 @@ function isObject2(value) {
|
|
|
21187
21356
|
|
|
21188
21357
|
// ../adapters/dist/src/redaction.js
|
|
21189
21358
|
var REDACTED = "[REDACTED]";
|
|
21359
|
+
var PRIVATE_KEY_PATTERN = /-----BEGIN (?:ENCRYPTED |RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----[\s\S]*?(?:-----END (?:ENCRYPTED |RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----|$)/g;
|
|
21190
21360
|
var DEFAULT_SECRET_PATTERNS = [
|
|
21191
|
-
/-----BEGIN (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----/g,
|
|
21192
21361
|
/\bAKIA[0-9A-Z]{16}\b/g,
|
|
21193
21362
|
/\b(?:ghp|github_pat|glpat|sk|xox[baprs])[-_][A-Za-z0-9_-]{16,}\b/g,
|
|
21194
21363
|
/\bBearer\s+[A-Za-z0-9._~+/=-]{8,}\b/gi,
|
|
@@ -21201,6 +21370,8 @@ var SENSITIVE_KEY_NAMES = /* @__PURE__ */ new Set([
|
|
|
21201
21370
|
"accesstoken",
|
|
21202
21371
|
"authtoken",
|
|
21203
21372
|
"authorization",
|
|
21373
|
+
"cookie",
|
|
21374
|
+
"setcookie",
|
|
21204
21375
|
"bearer",
|
|
21205
21376
|
"clientsecret",
|
|
21206
21377
|
"password",
|
|
@@ -21217,7 +21388,83 @@ var SENSITIVE_KEY_NAMES = /* @__PURE__ */ new Set([
|
|
|
21217
21388
|
]);
|
|
21218
21389
|
function redactText(value, options = {}) {
|
|
21219
21390
|
const replacement = options.replacement ?? REDACTED;
|
|
21220
|
-
return [...DEFAULT_SECRET_PATTERNS, ...options.extraPatterns ?? []].reduce(
|
|
21391
|
+
return [...DEFAULT_SECRET_PATTERNS, ...options.extraPatterns ?? []].reduce(
|
|
21392
|
+
(redacted, pattern) => redacted.replace(cloneGlobal(pattern), (match, prefix) => typeof prefix === "string" && prefix.length < match.length ? `${prefix}${replacement}` : replacement),
|
|
21393
|
+
// Mask PEM first: scanning `private_key: -----BEGIN ...` as an ordinary
|
|
21394
|
+
// assignment must not break its header and leave the following body public.
|
|
21395
|
+
redactSensitiveFields(value.replace(cloneGlobal(PRIVATE_KEY_PATTERN), () => replacement), replacement)
|
|
21396
|
+
);
|
|
21397
|
+
}
|
|
21398
|
+
function redactSensitiveFields(text, replacement) {
|
|
21399
|
+
const fields = /("(?:\\.|[^"\\\r\n])*"|'(?:\\.|[^'\\\r\n])*'|\b[A-Za-z_][A-Za-z0-9_.-]*)(\s*[:=]\s*)/gu;
|
|
21400
|
+
const parts = [];
|
|
21401
|
+
let retainedFrom = 0;
|
|
21402
|
+
let match;
|
|
21403
|
+
while ((match = fields.exec(text)) !== null) {
|
|
21404
|
+
const encodedKey = match[1];
|
|
21405
|
+
let key = encodedKey;
|
|
21406
|
+
if (encodedKey.startsWith('"')) {
|
|
21407
|
+
try {
|
|
21408
|
+
key = JSON.parse(encodedKey);
|
|
21409
|
+
} catch {
|
|
21410
|
+
continue;
|
|
21411
|
+
}
|
|
21412
|
+
} else if (encodedKey.startsWith("'"))
|
|
21413
|
+
key = encodedKey.slice(1, -1);
|
|
21414
|
+
if (!isSensitiveKey(key))
|
|
21415
|
+
continue;
|
|
21416
|
+
const start = fields.lastIndex;
|
|
21417
|
+
const end = sensitiveValueEnd(text, start, encodedKey[0] !== '"' && encodedKey[0] !== "'" && /^(?:authorization|cookie|set-cookie)$/iu.test(key));
|
|
21418
|
+
const quote = text[start];
|
|
21419
|
+
const masked = quote === "'" ? `'${replacement.replace(/\\/gu, "\\\\").replace(/'/gu, "\\'")}'` : quote === '"' || encodedKey.startsWith('"') ? JSON.stringify(replacement) : replacement;
|
|
21420
|
+
parts.push(text.slice(retainedFrom, start), masked);
|
|
21421
|
+
retainedFrom = end;
|
|
21422
|
+
fields.lastIndex = end;
|
|
21423
|
+
}
|
|
21424
|
+
return parts.length === 0 ? text : parts.join("") + text.slice(retainedFrom);
|
|
21425
|
+
}
|
|
21426
|
+
function sensitiveValueEnd(text, start, header) {
|
|
21427
|
+
if (header) {
|
|
21428
|
+
const end = text.indexOf("\n", start);
|
|
21429
|
+
return end < 0 ? text.length : end;
|
|
21430
|
+
}
|
|
21431
|
+
const first = text[start];
|
|
21432
|
+
if (first === '"' || first === "'") {
|
|
21433
|
+
for (let index2 = start + 1; index2 < text.length; index2++) {
|
|
21434
|
+
if (text[index2] === "\\")
|
|
21435
|
+
index2++;
|
|
21436
|
+
else if (text[index2] === first)
|
|
21437
|
+
return index2 + 1;
|
|
21438
|
+
}
|
|
21439
|
+
return text.length;
|
|
21440
|
+
}
|
|
21441
|
+
if (first === "{" || first === "[") {
|
|
21442
|
+
const closing = [first === "{" ? "}" : "]"];
|
|
21443
|
+
let quote;
|
|
21444
|
+
for (let index2 = start + 1; index2 < text.length; index2++) {
|
|
21445
|
+
const character = text[index2];
|
|
21446
|
+
if (quote !== void 0) {
|
|
21447
|
+
if (character === "\\")
|
|
21448
|
+
index2++;
|
|
21449
|
+
else if (character === quote)
|
|
21450
|
+
quote = void 0;
|
|
21451
|
+
} else if (character === '"' || character === "'")
|
|
21452
|
+
quote = character;
|
|
21453
|
+
else if (character === "{" || character === "[")
|
|
21454
|
+
closing.push(character === "{" ? "}" : "]");
|
|
21455
|
+
else if (character === "}" || character === "]") {
|
|
21456
|
+
if (character !== closing.pop())
|
|
21457
|
+
return text.length;
|
|
21458
|
+
if (closing.length === 0)
|
|
21459
|
+
return index2 + 1;
|
|
21460
|
+
}
|
|
21461
|
+
}
|
|
21462
|
+
return text.length;
|
|
21463
|
+
}
|
|
21464
|
+
let index = start;
|
|
21465
|
+
while (index < text.length && !/[\s,;}\]]/u.test(text[index]))
|
|
21466
|
+
index++;
|
|
21467
|
+
return index;
|
|
21221
21468
|
}
|
|
21222
21469
|
function redactValue(value, options = {}) {
|
|
21223
21470
|
if (typeof value === "string")
|
|
@@ -21239,6 +21486,208 @@ function cloneGlobal(pattern) {
|
|
|
21239
21486
|
return new RegExp(pattern.source, pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`);
|
|
21240
21487
|
}
|
|
21241
21488
|
|
|
21489
|
+
// ../adapters/dist/src/live-output.js
|
|
21490
|
+
import { randomUUID } from "node:crypto";
|
|
21491
|
+
var MAX_ITEMS = 128;
|
|
21492
|
+
var MAX_INPUT_BYTES = 96 * 1024;
|
|
21493
|
+
var MAX_PUBLIC_BYTES = 24 * 1024;
|
|
21494
|
+
var MAX_PUBLICATIONS = 1200;
|
|
21495
|
+
function createLiveOutputPublisher(options) {
|
|
21496
|
+
const items = /* @__PURE__ */ new Map();
|
|
21497
|
+
const now = options.now ?? Date.now;
|
|
21498
|
+
const intervalMs = options.intervalMs ?? 1500;
|
|
21499
|
+
let lastPublished, publications = 0, closed = false;
|
|
21500
|
+
let timer;
|
|
21501
|
+
let queue = Promise.resolve();
|
|
21502
|
+
let lastVisited;
|
|
21503
|
+
const serial = (operation) => {
|
|
21504
|
+
queue = queue.then(operation, operation);
|
|
21505
|
+
return queue;
|
|
21506
|
+
};
|
|
21507
|
+
const itemFor = (key, kind, title) => {
|
|
21508
|
+
let item = items.get(key);
|
|
21509
|
+
if (!item && items.size < MAX_ITEMS) {
|
|
21510
|
+
item = {
|
|
21511
|
+
streamId: randomUUID(),
|
|
21512
|
+
raw: "",
|
|
21513
|
+
kind,
|
|
21514
|
+
state: "running",
|
|
21515
|
+
revision: 0,
|
|
21516
|
+
acknowledged: "",
|
|
21517
|
+
dirty: true,
|
|
21518
|
+
truncated: false
|
|
21519
|
+
};
|
|
21520
|
+
items.set(key, item);
|
|
21521
|
+
}
|
|
21522
|
+
if (item && title !== void 0)
|
|
21523
|
+
item.title = bound(redactText(title, options.redaction), 256);
|
|
21524
|
+
return item;
|
|
21525
|
+
};
|
|
21526
|
+
const safe = (item) => {
|
|
21527
|
+
let content = item.raw;
|
|
21528
|
+
if (item.state === "running") {
|
|
21529
|
+
content = content.replace(/(?:\bBearer\s+|\b(?:api[_-]?key|access[_-]?token|auth[_-]?token|client[_-]?secret|password|passwd|secret|token)["']?\s*[=:]\s*["']?)[^\n,;]*$/giu, "");
|
|
21530
|
+
let end = content.length;
|
|
21531
|
+
while (end > 0 && /[A-Za-z0-9_./~+=:@%\-]/u.test(content[end - 1]))
|
|
21532
|
+
end--;
|
|
21533
|
+
content = content.slice(0, end);
|
|
21534
|
+
}
|
|
21535
|
+
content = redactText(content, options.redaction);
|
|
21536
|
+
return bound(content, MAX_PUBLIC_BYTES, item.truncated);
|
|
21537
|
+
};
|
|
21538
|
+
const signatureFor = (item) => JSON.stringify([safe(item), item.state, item.title, item.plan]);
|
|
21539
|
+
const schedule = () => {
|
|
21540
|
+
if (closed || options.schedule === false || timer || ![...items.values()].some((x) => x.dirty))
|
|
21541
|
+
return;
|
|
21542
|
+
timer = setTimeout(() => {
|
|
21543
|
+
timer = void 0;
|
|
21544
|
+
void flush().catch(() => void 0);
|
|
21545
|
+
}, intervalMs);
|
|
21546
|
+
timer.unref();
|
|
21547
|
+
};
|
|
21548
|
+
const publishOne = async (item) => {
|
|
21549
|
+
if (!item.dirty || publications >= MAX_PUBLICATIONS)
|
|
21550
|
+
return;
|
|
21551
|
+
const content = safe(item);
|
|
21552
|
+
const signature = JSON.stringify([content, item.state, item.title, item.plan]);
|
|
21553
|
+
if (!item.pending && signature === item.acknowledged) {
|
|
21554
|
+
item.dirty = false;
|
|
21555
|
+
return;
|
|
21556
|
+
}
|
|
21557
|
+
if (!item.pending && !content.trim() && item.plan === void 0)
|
|
21558
|
+
return;
|
|
21559
|
+
const revision = item.revision + 1;
|
|
21560
|
+
const update = {
|
|
21561
|
+
id: `${item.streamId}:${revision}`,
|
|
21562
|
+
content,
|
|
21563
|
+
phase: "stream",
|
|
21564
|
+
streamId: item.streamId,
|
|
21565
|
+
streamMode: "snapshot",
|
|
21566
|
+
streamKind: item.kind,
|
|
21567
|
+
streamRevision: revision,
|
|
21568
|
+
streamState: item.state,
|
|
21569
|
+
...item.title === void 0 ? {} : { title: item.title },
|
|
21570
|
+
...item.plan === void 0 ? {} : { plan: item.plan }
|
|
21571
|
+
};
|
|
21572
|
+
item.pending ??= { update, signature };
|
|
21573
|
+
const pending = item.pending;
|
|
21574
|
+
try {
|
|
21575
|
+
if (await options.publish(pending.update) === false)
|
|
21576
|
+
return;
|
|
21577
|
+
item.revision = pending.update.streamRevision;
|
|
21578
|
+
item.acknowledged = pending.signature;
|
|
21579
|
+
delete item.pending;
|
|
21580
|
+
item.dirty = signatureFor(item) !== item.acknowledged;
|
|
21581
|
+
lastPublished = now();
|
|
21582
|
+
publications++;
|
|
21583
|
+
} catch {
|
|
21584
|
+
}
|
|
21585
|
+
};
|
|
21586
|
+
const flush = () => serial(async () => {
|
|
21587
|
+
if (closed || lastPublished !== void 0 && now() - lastPublished < intervalMs) {
|
|
21588
|
+
schedule();
|
|
21589
|
+
return;
|
|
21590
|
+
}
|
|
21591
|
+
const ordered = [...items.values()];
|
|
21592
|
+
const start = lastVisited === void 0 ? 0 : (ordered.indexOf(lastVisited) + 1) % ordered.length;
|
|
21593
|
+
for (let offset = 0; offset < ordered.length; offset++) {
|
|
21594
|
+
const item = ordered[(start + offset) % ordered.length];
|
|
21595
|
+
if (!item.dirty)
|
|
21596
|
+
continue;
|
|
21597
|
+
lastVisited = item;
|
|
21598
|
+
await publishOne(item);
|
|
21599
|
+
if (lastPublished !== void 0 && now() - lastPublished < intervalMs)
|
|
21600
|
+
break;
|
|
21601
|
+
}
|
|
21602
|
+
schedule();
|
|
21603
|
+
});
|
|
21604
|
+
return {
|
|
21605
|
+
async onDelta(key, delta, kind = "answer", title) {
|
|
21606
|
+
if (closed || !delta)
|
|
21607
|
+
return;
|
|
21608
|
+
const item = itemFor(key, kind, title);
|
|
21609
|
+
if (!item || item.state !== "running" || item.truncated)
|
|
21610
|
+
return;
|
|
21611
|
+
const raw = item.raw + delta;
|
|
21612
|
+
item.raw = bound(raw, MAX_INPUT_BYTES);
|
|
21613
|
+
item.truncated = Buffer.byteLength(raw) > MAX_INPUT_BYTES;
|
|
21614
|
+
item.dirty = true;
|
|
21615
|
+
await flush();
|
|
21616
|
+
},
|
|
21617
|
+
async onSnapshot(key, text, kind = "answer", title, state = "running") {
|
|
21618
|
+
if (closed)
|
|
21619
|
+
return;
|
|
21620
|
+
const item = itemFor(key, kind, title);
|
|
21621
|
+
if (!item)
|
|
21622
|
+
return;
|
|
21623
|
+
item.raw = bound(text, MAX_INPUT_BYTES);
|
|
21624
|
+
item.truncated = Buffer.byteLength(text) > MAX_INPUT_BYTES;
|
|
21625
|
+
item.state = state;
|
|
21626
|
+
item.dirty = true;
|
|
21627
|
+
await flush();
|
|
21628
|
+
},
|
|
21629
|
+
async onPlan(key, steps) {
|
|
21630
|
+
if (closed)
|
|
21631
|
+
return;
|
|
21632
|
+
const item = itemFor(key, "plan");
|
|
21633
|
+
if (!item)
|
|
21634
|
+
return;
|
|
21635
|
+
item.plan = steps.slice(0, 64).map((step) => ({ step: bound(redactText(step.step, options.redaction), 512), status: step.status }));
|
|
21636
|
+
item.raw = item.plan.map((step) => `${step.status}: ${step.step}`).join("\n");
|
|
21637
|
+
item.dirty = true;
|
|
21638
|
+
await flush();
|
|
21639
|
+
},
|
|
21640
|
+
flush,
|
|
21641
|
+
async finish(success2 = true) {
|
|
21642
|
+
if (timer) {
|
|
21643
|
+
clearTimeout(timer);
|
|
21644
|
+
timer = void 0;
|
|
21645
|
+
}
|
|
21646
|
+
await serial(async () => {
|
|
21647
|
+
if (closed)
|
|
21648
|
+
return;
|
|
21649
|
+
for (const item of [...items.values()].slice(0, 64)) {
|
|
21650
|
+
if (item.state === "running") {
|
|
21651
|
+
item.state = success2 ? "completed" : "failed";
|
|
21652
|
+
item.dirty = true;
|
|
21653
|
+
}
|
|
21654
|
+
await publishOne(item);
|
|
21655
|
+
if (item.dirty && !item.pending)
|
|
21656
|
+
await publishOne(item);
|
|
21657
|
+
}
|
|
21658
|
+
closed = true;
|
|
21659
|
+
items.clear();
|
|
21660
|
+
});
|
|
21661
|
+
},
|
|
21662
|
+
lastPublishedAt: () => lastPublished
|
|
21663
|
+
};
|
|
21664
|
+
}
|
|
21665
|
+
function liveOutputPayload(update) {
|
|
21666
|
+
return {
|
|
21667
|
+
content: update.content,
|
|
21668
|
+
phase: update.phase,
|
|
21669
|
+
stream_id: update.streamId,
|
|
21670
|
+
stream_mode: update.streamMode,
|
|
21671
|
+
stream_kind: update.streamKind,
|
|
21672
|
+
stream_revision: update.streamRevision,
|
|
21673
|
+
stream_state: update.streamState,
|
|
21674
|
+
...update.title === void 0 ? {} : { title: update.title },
|
|
21675
|
+
...update.plan === void 0 ? {} : { plan: update.plan.map((step) => ({ step: step.step, status: step.status })) }
|
|
21676
|
+
};
|
|
21677
|
+
}
|
|
21678
|
+
function bound(text, maxBytes, alreadyTruncated = false) {
|
|
21679
|
+
if (!alreadyTruncated && Buffer.byteLength(text) <= maxBytes)
|
|
21680
|
+
return text;
|
|
21681
|
+
const suffix = "\n[TRUNCATED]";
|
|
21682
|
+
const bytes2 = Buffer.from(text).subarray(0, maxBytes - Buffer.byteLength(suffix));
|
|
21683
|
+
let end = bytes2.length;
|
|
21684
|
+
while (end > 0 && (bytes2[end - 1] & 192) === 128)
|
|
21685
|
+
end--;
|
|
21686
|
+
if (end < bytes2.length || (bytes2[end - 1] & 128) !== 0)
|
|
21687
|
+
end = Math.max(0, end - 1);
|
|
21688
|
+
return bytes2.subarray(0, end).toString("utf8") + suffix;
|
|
21689
|
+
}
|
|
21690
|
+
|
|
21242
21691
|
// ../adapters/dist/src/jsonl.js
|
|
21243
21692
|
var DEFAULT_MAX_READ_BYTES = 4 * 1024 * 1024;
|
|
21244
21693
|
|
|
@@ -21445,7 +21894,7 @@ function isNodeError(error62) {
|
|
|
21445
21894
|
var MAX_FRAME_BYTES = 1024 * 1024;
|
|
21446
21895
|
|
|
21447
21896
|
// ../bridge/dist/src/code-sync.js
|
|
21448
|
-
import { createHash as createHash2, randomUUID } from "node:crypto";
|
|
21897
|
+
import { createHash as createHash2, randomUUID as randomUUID2 } from "node:crypto";
|
|
21449
21898
|
import { execFile } from "node:child_process";
|
|
21450
21899
|
import { constants } from "node:fs";
|
|
21451
21900
|
import { chmod as chmod2, lstat as lstat2, mkdir as mkdir2, open as open3, readFile as readFile2, realpath, rename, unlink } from "node:fs/promises";
|
|
@@ -21635,7 +22084,7 @@ var ProjectCodeSync = class _ProjectCodeSync {
|
|
|
21635
22084
|
if (!sameHashes(current.hashes, binding.baseline))
|
|
21636
22085
|
throw new CodeSyncError("code_sync_dirty", "Local files have unuploaded changes. Upload first, or recover cloud code into a new folder.");
|
|
21637
22086
|
await applySnapshot(this.#root, snapshot.files, binding.baseline, {
|
|
21638
|
-
backupRoot: path2.join(this.#stateRoot, "download-backups",
|
|
22087
|
+
backupRoot: path2.join(this.#stateRoot, "download-backups", randomUUID2()),
|
|
21639
22088
|
beforeWrite: async () => {
|
|
21640
22089
|
binding.interrupted_download = true;
|
|
21641
22090
|
await this.#save(binding);
|
|
@@ -21679,7 +22128,7 @@ var ProjectCodeSync = class _ProjectCodeSync {
|
|
|
21679
22128
|
const recoveryStem = [...path2.basename(this.#root)];
|
|
21680
22129
|
while (Buffer.byteLength(recoveryStem.join("")) > 180)
|
|
21681
22130
|
recoveryStem.pop();
|
|
21682
|
-
const recoveryName = `${recoveryStem.join("")}-recovered-${(/* @__PURE__ */ new Date()).toISOString().replace(/[^0-9]/gu, "").slice(0, 14)}-${
|
|
22131
|
+
const recoveryName = `${recoveryStem.join("")}-recovered-${(/* @__PURE__ */ new Date()).toISOString().replace(/[^0-9]/gu, "").slice(0, 14)}-${randomUUID2().slice(0, 8)}`;
|
|
21683
22132
|
const recoveryPath = path2.join(path2.dirname(this.#root), recoveryName);
|
|
21684
22133
|
await mkdir2(recoveryPath, { mode: 448 });
|
|
21685
22134
|
await applySnapshot(recoveryPath, snapshot.files, {}, void 0, this.#limits);
|
|
@@ -22126,7 +22575,7 @@ async function git(args, cwd, maxBuffer = 2 * 1024 * 1024) {
|
|
|
22126
22575
|
}
|
|
22127
22576
|
}
|
|
22128
22577
|
async function writePrivate(filename, content) {
|
|
22129
|
-
const temporary = `${filename}.${
|
|
22578
|
+
const temporary = `${filename}.${randomUUID2()}.tmp`;
|
|
22130
22579
|
const handle = await open3(temporary, "wx", 384);
|
|
22131
22580
|
try {
|
|
22132
22581
|
await handle.writeFile(content);
|
|
@@ -22222,7 +22671,7 @@ async function applySnapshot(root, files, baseline, options, limits = CLOUD_CODE
|
|
|
22222
22671
|
if (!await safeAncestors(root, file2.path, true) || await fileHash(root, file2.path, options?.baselineExecutables?.has(file2.path), limits.maxFileBytes) !== baseline[file2.path])
|
|
22223
22672
|
throw new CodeSyncError("code_sync_busy", "Local files changed during download. No further files were applied.");
|
|
22224
22673
|
const filename = path2.join(root, ...file2.path.split("/"));
|
|
22225
|
-
const temporary = path2.join(path2.dirname(filename), `.gatherthread-${
|
|
22674
|
+
const temporary = path2.join(path2.dirname(filename), `.gatherthread-${randomUUID2()}.tmp`);
|
|
22226
22675
|
const handle = await open3(temporary, "wx", file2.executable ? 448 : 384);
|
|
22227
22676
|
try {
|
|
22228
22677
|
await handle.writeFile(Buffer.from(file2.content_base64, "base64"));
|
|
@@ -22246,7 +22695,7 @@ async function applySnapshot(root, files, baseline, options, limits = CLOUD_CODE
|
|
|
22246
22695
|
}
|
|
22247
22696
|
|
|
22248
22697
|
// ../bridge/dist/src/github-code-sync.js
|
|
22249
|
-
import { createHash as createHash3, randomUUID as
|
|
22698
|
+
import { createHash as createHash3, randomUUID as randomUUID3 } from "node:crypto";
|
|
22250
22699
|
import { spawn } from "node:child_process";
|
|
22251
22700
|
import { constants as constants2 } from "node:fs";
|
|
22252
22701
|
import { lstat as lstat3, mkdir as mkdir3, open as open4, unlink as unlink2 } from "node:fs/promises";
|
|
@@ -22443,7 +22892,7 @@ var GitHubCodeStorage = class {
|
|
|
22443
22892
|
async #tree(files) {
|
|
22444
22893
|
if (!filesSchema.safeParse(files).success)
|
|
22445
22894
|
throw new CodeSyncError("code_sync_limit", "Source tree exceeds GitHub checkpoint limits.");
|
|
22446
|
-
const index = path3.join(this.#directory, `index-${
|
|
22895
|
+
const index = path3.join(this.#directory, `index-${randomUUID3()}`);
|
|
22447
22896
|
try {
|
|
22448
22897
|
await this.#git(["read-tree", "--empty"], void 0, index);
|
|
22449
22898
|
const records = [];
|
|
@@ -22639,7 +23088,7 @@ import path10 from "node:path";
|
|
|
22639
23088
|
// dist/src/code-sync-controller.js
|
|
22640
23089
|
import { constants as constants3 } from "node:fs";
|
|
22641
23090
|
import { lstat as lstat5, mkdir as mkdir4, open as open5, rename as rename2, unlink as unlink3 } from "node:fs/promises";
|
|
22642
|
-
import { randomUUID as
|
|
23091
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
22643
23092
|
import path5 from "node:path";
|
|
22644
23093
|
|
|
22645
23094
|
// dist/src/path-security.js
|
|
@@ -22902,7 +23351,7 @@ async function saveConsent(file2, binding, enabled) {
|
|
|
22902
23351
|
await mkdir4(path5.dirname(file2), { recursive: true, mode: 448 });
|
|
22903
23352
|
const ancestors = await secureDirectoryChain(path5.dirname(file2));
|
|
22904
23353
|
await loadConsent(file2, binding);
|
|
22905
|
-
const temporary = `${file2}.${
|
|
23354
|
+
const temporary = `${file2}.${randomUUID4()}.tmp`;
|
|
22906
23355
|
const handle = await open5(temporary, "wx", 384);
|
|
22907
23356
|
try {
|
|
22908
23357
|
await handle.writeFile(JSON.stringify({ version: 1, binding, enabled }));
|
|
@@ -23677,6 +24126,255 @@ function asObject2(value) {
|
|
|
23677
24126
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
23678
24127
|
}
|
|
23679
24128
|
|
|
24129
|
+
// dist/src/live-event-mapper.js
|
|
24130
|
+
var MAX_ATTEMPTS = 64;
|
|
24131
|
+
var MAX_BLOCKS = 128;
|
|
24132
|
+
var MAX_TEXT = 96 * 1024;
|
|
24133
|
+
function createDshLiveEventMapper(publisher) {
|
|
24134
|
+
const attempts = /* @__PURE__ */ new Map();
|
|
24135
|
+
const steps = /* @__PURE__ */ new Map();
|
|
24136
|
+
const tools = /* @__PURE__ */ new Map();
|
|
24137
|
+
let revision = 0;
|
|
24138
|
+
const deliver = (operation) => {
|
|
24139
|
+
void operation.catch(() => void 0);
|
|
24140
|
+
};
|
|
24141
|
+
const snapshot = (block, state) => deliver(publisher.onSnapshot(block.key, block.text, block.kind, block.title, state));
|
|
24142
|
+
const toolFor = (id, fallbackKey) => {
|
|
24143
|
+
let tool = tools.get(id);
|
|
24144
|
+
if (tool === void 0 && tools.size < MAX_BLOCKS) {
|
|
24145
|
+
tool = { key: fallbackKey, arguments: "" };
|
|
24146
|
+
tools.set(id, tool);
|
|
24147
|
+
}
|
|
24148
|
+
return tool;
|
|
24149
|
+
};
|
|
24150
|
+
const settle2 = (attempt, state) => {
|
|
24151
|
+
if (state === "failed")
|
|
24152
|
+
attempt.failed = true;
|
|
24153
|
+
for (const block of attempt.blocks.values()) {
|
|
24154
|
+
if (block.kind !== "tool")
|
|
24155
|
+
snapshot(block, state);
|
|
24156
|
+
else if (state === "failed") {
|
|
24157
|
+
const argumentsText = block.callId === void 0 ? void 0 : tools.get(block.callId)?.arguments;
|
|
24158
|
+
deliver(publisher.onSnapshot(block.key, `Arguments:
|
|
24159
|
+
${argumentsText || "[Unparseable tool arguments]"}`, "tool", block.title, state));
|
|
24160
|
+
}
|
|
24161
|
+
}
|
|
24162
|
+
};
|
|
24163
|
+
const onFrame = (frame) => {
|
|
24164
|
+
if (frame.revision <= revision)
|
|
24165
|
+
return;
|
|
24166
|
+
const identity = frame.attemptId;
|
|
24167
|
+
if (frame.type === "start") {
|
|
24168
|
+
if (attempts.has(identity) || attempts.size >= MAX_ATTEMPTS)
|
|
24169
|
+
return;
|
|
24170
|
+
revision = frame.revision;
|
|
24171
|
+
const attempt2 = { turn: frame.turn, step: frame.step, nextIndex: 0, closed: false, failed: false, blocks: /* @__PURE__ */ new Map() };
|
|
24172
|
+
attempts.set(identity, attempt2);
|
|
24173
|
+
steps.set(`${frame.turn}:${frame.step}`, attempt2);
|
|
24174
|
+
return;
|
|
24175
|
+
}
|
|
24176
|
+
const attempt = attempts.get(identity);
|
|
24177
|
+
if (attempt === void 0 || attempt.closed || frame.index !== attempt.nextIndex)
|
|
24178
|
+
return;
|
|
24179
|
+
revision = frame.revision;
|
|
24180
|
+
if (frame.type === "end") {
|
|
24181
|
+
attempt.closed = true;
|
|
24182
|
+
settle2(attempt, attempt.failed || frame.outcome.kind === "abandoned" || frame.outcome.eventType === "assistant/attempt" ? "failed" : "completed");
|
|
24183
|
+
return;
|
|
24184
|
+
}
|
|
24185
|
+
attempt.nextIndex++;
|
|
24186
|
+
const chunk = object2(frame.chunk);
|
|
24187
|
+
if (chunk?.type === "finish") {
|
|
24188
|
+
const reason = object2(chunk.reason)?.kind ?? chunk.reason;
|
|
24189
|
+
if (reason === "error" || reason === "aborted")
|
|
24190
|
+
settle2(attempt, "failed");
|
|
24191
|
+
return;
|
|
24192
|
+
}
|
|
24193
|
+
if (!integer2(chunk?.index) || Number(chunk.index) >= MAX_BLOCKS)
|
|
24194
|
+
return;
|
|
24195
|
+
const index = Number(chunk.index);
|
|
24196
|
+
if (chunk.type === "block-start") {
|
|
24197
|
+
const kind = chunk.blockType === "text" ? "answer" : chunk.blockType === "reasoning" ? "reasoning" : chunk.blockType === "tool-call" ? "tool" : void 0;
|
|
24198
|
+
if (kind !== void 0 && !attempt.blocks.has(index)) {
|
|
24199
|
+
attempt.blocks.set(index, { key: `${identity}:${index}`, kind, text: "" });
|
|
24200
|
+
}
|
|
24201
|
+
return;
|
|
24202
|
+
}
|
|
24203
|
+
const block = attempt.blocks.get(index);
|
|
24204
|
+
if (block === void 0)
|
|
24205
|
+
return;
|
|
24206
|
+
if (chunk.type === "text-delta" && block.kind === "answer" || chunk.type === "reasoning-delta" && block.kind === "reasoning") {
|
|
24207
|
+
if (typeof chunk.text !== "string")
|
|
24208
|
+
return;
|
|
24209
|
+
block.text = bound2(block.text + chunk.text);
|
|
24210
|
+
deliver(publisher.onDelta(block.key, chunk.text, block.kind));
|
|
24211
|
+
} else if (chunk.type === "tool-call-delta" && block.kind === "tool") {
|
|
24212
|
+
if (!identifier(chunk.id) || typeof chunk.argumentsDelta !== "string" || block.callId !== void 0 && block.callId !== chunk.id)
|
|
24213
|
+
return;
|
|
24214
|
+
block.callId = chunk.id;
|
|
24215
|
+
if (typeof chunk.name === "string")
|
|
24216
|
+
block.title = bound2(chunk.name).slice(0, 256);
|
|
24217
|
+
const tool = toolFor(block.callId, block.key);
|
|
24218
|
+
if (tool === void 0)
|
|
24219
|
+
return;
|
|
24220
|
+
block.key = tool.key;
|
|
24221
|
+
block.text = bound2(block.text + chunk.argumentsDelta);
|
|
24222
|
+
if (block.title !== void 0)
|
|
24223
|
+
tool.title = block.title;
|
|
24224
|
+
const argumentsText = parsedArguments(block.text);
|
|
24225
|
+
if (argumentsText !== void 0)
|
|
24226
|
+
tool.arguments = argumentsText;
|
|
24227
|
+
deliver(publisher.onSnapshot(block.key, argumentsText === void 0 ? "Preparing tool arguments.\n" : `Arguments:
|
|
24228
|
+
${argumentsText}`, "tool", block.title));
|
|
24229
|
+
} else if (chunk.type === "block-end") {
|
|
24230
|
+
const content = object2(chunk.block);
|
|
24231
|
+
if ((content?.type === "text" && block.kind === "answer" || content?.type === "reasoning" && block.kind === "reasoning") && typeof content.text === "string") {
|
|
24232
|
+
block.text = bound2(content.text);
|
|
24233
|
+
snapshot(block, "completed");
|
|
24234
|
+
} else if (content?.type === "tool-call" && block.kind === "tool" && identifier(content.id) && typeof content.arguments === "string" && (block.callId === void 0 || content.id === block.callId)) {
|
|
24235
|
+
const tool = toolFor(content.id, block.key);
|
|
24236
|
+
if (tool === void 0)
|
|
24237
|
+
return;
|
|
24238
|
+
block.callId = content.id;
|
|
24239
|
+
block.key = tool.key;
|
|
24240
|
+
block.text = publicArguments(content.arguments);
|
|
24241
|
+
if (typeof content.name === "string")
|
|
24242
|
+
block.title = content.name.slice(0, 256);
|
|
24243
|
+
tool.arguments = block.text;
|
|
24244
|
+
if (block.title !== void 0)
|
|
24245
|
+
tool.title = block.title;
|
|
24246
|
+
snapshot(block, "running");
|
|
24247
|
+
}
|
|
24248
|
+
}
|
|
24249
|
+
};
|
|
24250
|
+
const onDurable = (event) => {
|
|
24251
|
+
const data = object2(event.data);
|
|
24252
|
+
if (data === void 0)
|
|
24253
|
+
return;
|
|
24254
|
+
if (event.type === "assistant/message" && integer2(data.turn) && integer2(data.step)) {
|
|
24255
|
+
const attempt = steps.get(`${data.turn}:${data.step}`);
|
|
24256
|
+
if (attempt !== void 0 && data.interrupted === true)
|
|
24257
|
+
attempt.failed = true;
|
|
24258
|
+
const message = object2(data.message);
|
|
24259
|
+
if (!Array.isArray(message?.content))
|
|
24260
|
+
return;
|
|
24261
|
+
const nativeBlocks = [...attempt?.blocks.values() ?? []];
|
|
24262
|
+
for (const [index, value] of message.content.slice(0, MAX_BLOCKS).entries()) {
|
|
24263
|
+
const content = object2(value);
|
|
24264
|
+
const kind = content?.type === "text" ? "answer" : content?.type === "reasoning" ? "reasoning" : void 0;
|
|
24265
|
+
if (kind !== void 0 && typeof content.text === "string") {
|
|
24266
|
+
const candidate = nativeBlocks[index];
|
|
24267
|
+
const key = candidate?.kind === kind ? candidate.key : `assistant:${event.seq}:${index}`;
|
|
24268
|
+
if (candidate?.kind === kind)
|
|
24269
|
+
candidate.text = bound2(content.text);
|
|
24270
|
+
deliver(publisher.onSnapshot(key, content.text, kind, void 0, data.interrupted === true ? "failed" : "completed"));
|
|
24271
|
+
}
|
|
24272
|
+
}
|
|
24273
|
+
} else if (event.type === "assistant/attempt" && integer2(data.turn) && integer2(data.step)) {
|
|
24274
|
+
const attempt = steps.get(`${data.turn}:${data.step}`);
|
|
24275
|
+
if (attempt !== void 0)
|
|
24276
|
+
settle2(attempt, "failed");
|
|
24277
|
+
} else if (event.type === "tool/call" && identifier(data.callId) && typeof data.name === "string" && typeof data.arguments === "string") {
|
|
24278
|
+
const tool = toolFor(data.callId, `tool:${event.seq}`);
|
|
24279
|
+
if (tool === void 0)
|
|
24280
|
+
return;
|
|
24281
|
+
tool.arguments = publicArguments(data.arguments);
|
|
24282
|
+
tool.title = data.name.slice(0, 256);
|
|
24283
|
+
deliver(publisher.onSnapshot(tool.key, `Arguments:
|
|
24284
|
+
${tool.arguments}`, "tool", tool.title));
|
|
24285
|
+
} else if (event.type === "tool/result") {
|
|
24286
|
+
const message = object2(data.message);
|
|
24287
|
+
const content = Array.isArray(message?.content) ? message.content : [];
|
|
24288
|
+
const wrapped = content.map(object2).find((block) => block?.type === "tool-result");
|
|
24289
|
+
const id = wrapped?.toolCallId ?? message?.toolCallId;
|
|
24290
|
+
if (!identifier(id))
|
|
24291
|
+
return;
|
|
24292
|
+
const tool = tools.get(id);
|
|
24293
|
+
if (tool === void 0)
|
|
24294
|
+
return;
|
|
24295
|
+
const blocks = wrapped === void 0 ? content : wrapped.content;
|
|
24296
|
+
if (!Array.isArray(blocks))
|
|
24297
|
+
return;
|
|
24298
|
+
const text = blocks.slice(0, MAX_BLOCKS).flatMap((value) => {
|
|
24299
|
+
const block = object2(value);
|
|
24300
|
+
return block?.type === "text" && typeof block.text === "string" ? [bound2(block.text)] : [];
|
|
24301
|
+
}).join("");
|
|
24302
|
+
const failed = wrapped?.isError === true || message?.isError === true || data.error !== void 0;
|
|
24303
|
+
deliver(publisher.onSnapshot(tool.key, `Arguments:
|
|
24304
|
+
${tool.arguments}
|
|
24305
|
+
|
|
24306
|
+
Result:
|
|
24307
|
+
${bound2(text)}`, "tool", tool.title, failed ? "failed" : "completed"));
|
|
24308
|
+
} else if (event.type === "todo/write" && Array.isArray(data.todos) && data.todos.length <= 64) {
|
|
24309
|
+
const plan = [];
|
|
24310
|
+
for (const value of data.todos) {
|
|
24311
|
+
const item = object2(value);
|
|
24312
|
+
if (typeof item?.content !== "string" || !["pending", "in_progress", "completed"].includes(String(item.status)))
|
|
24313
|
+
return;
|
|
24314
|
+
plan.push({ step: item.content, status: item.status });
|
|
24315
|
+
}
|
|
24316
|
+
deliver(publisher.onPlan("plan", plan));
|
|
24317
|
+
}
|
|
24318
|
+
};
|
|
24319
|
+
return {
|
|
24320
|
+
onEvent(event) {
|
|
24321
|
+
if (event.kind === "assistant-stream")
|
|
24322
|
+
onFrame(event.frame);
|
|
24323
|
+
else
|
|
24324
|
+
onDurable(event.event);
|
|
24325
|
+
},
|
|
24326
|
+
async finish(success2 = true) {
|
|
24327
|
+
await publisher.finish(success2);
|
|
24328
|
+
}
|
|
24329
|
+
};
|
|
24330
|
+
}
|
|
24331
|
+
function parseDshAssistantStreamFrame(value) {
|
|
24332
|
+
const frame = object2(value);
|
|
24333
|
+
if (!identifier(frame?.attemptId) || !integer2(frame?.revision) || Number(frame.revision) < 1)
|
|
24334
|
+
return void 0;
|
|
24335
|
+
const shared = { attemptId: frame.attemptId, revision: Number(frame.revision) };
|
|
24336
|
+
if (frame.type === "start" && integer2(frame.turn) && integer2(frame.step)) {
|
|
24337
|
+
return { type: "start", ...shared, turn: Number(frame.turn), step: Number(frame.step) };
|
|
24338
|
+
}
|
|
24339
|
+
if (frame.type === "chunk" && integer2(frame.index) && integer2(frame.time) && object2(frame.chunk) !== void 0) {
|
|
24340
|
+
return { type: "chunk", ...shared, index: Number(frame.index), time: Number(frame.time), chunk: frame.chunk };
|
|
24341
|
+
}
|
|
24342
|
+
const outcome = object2(frame.outcome);
|
|
24343
|
+
if (frame.type === "end" && integer2(frame.index)) {
|
|
24344
|
+
if (outcome?.kind === "abandoned")
|
|
24345
|
+
return { type: "end", ...shared, index: Number(frame.index), outcome: { kind: "abandoned" } };
|
|
24346
|
+
if (outcome?.kind === "committed" && integer2(outcome.seq) && (outcome.eventType === "assistant/message" || outcome.eventType === "assistant/attempt")) {
|
|
24347
|
+
return { type: "end", ...shared, index: Number(frame.index), outcome: { kind: "committed", eventType: outcome.eventType, seq: Number(outcome.seq) } };
|
|
24348
|
+
}
|
|
24349
|
+
}
|
|
24350
|
+
return void 0;
|
|
24351
|
+
}
|
|
24352
|
+
function publicArguments(text) {
|
|
24353
|
+
return parsedArguments(text) ?? "[Unparseable tool arguments]";
|
|
24354
|
+
}
|
|
24355
|
+
function parsedArguments(text) {
|
|
24356
|
+
if (text.length > MAX_TEXT)
|
|
24357
|
+
return void 0;
|
|
24358
|
+
try {
|
|
24359
|
+
return JSON.stringify(redactValue(JSON.parse(text)));
|
|
24360
|
+
} catch {
|
|
24361
|
+
return void 0;
|
|
24362
|
+
}
|
|
24363
|
+
}
|
|
24364
|
+
function bound2(text) {
|
|
24365
|
+
return text.length > MAX_TEXT ? `${text.slice(0, MAX_TEXT)}
|
|
24366
|
+
[TRUNCATED]` : text;
|
|
24367
|
+
}
|
|
24368
|
+
function integer2(value) {
|
|
24369
|
+
return Number.isSafeInteger(value) && Number(value) >= 0;
|
|
24370
|
+
}
|
|
24371
|
+
function identifier(value) {
|
|
24372
|
+
return typeof value === "string" && value.length > 0 && value.length <= 512;
|
|
24373
|
+
}
|
|
24374
|
+
function object2(value) {
|
|
24375
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
24376
|
+
}
|
|
24377
|
+
|
|
23680
24378
|
// dist/src/connector.js
|
|
23681
24379
|
var INTERRUPTED_REQUEST_CONTINUATION = "Continue the interrupted GatherThread request using the DSH Session context already restored by the Host. Return only the public final answer.";
|
|
23682
24380
|
var LIVE_PROGRESS_MIN_INTERVAL_MS = 6e4;
|
|
@@ -23704,6 +24402,7 @@ var DshHostConnector = class {
|
|
|
23704
24402
|
#publicationPromise;
|
|
23705
24403
|
#heartbeatOffline = false;
|
|
23706
24404
|
#liveProgressPromise = Promise.resolve();
|
|
24405
|
+
#activeLiveOutput;
|
|
23707
24406
|
#lastLiveProgressKey;
|
|
23708
24407
|
#lastLiveProgressAt = 0;
|
|
23709
24408
|
#stopPromise;
|
|
@@ -23714,6 +24413,8 @@ var DshHostConnector = class {
|
|
|
23714
24413
|
#activeExecutionSelection;
|
|
23715
24414
|
#summaryScanSequence = 0;
|
|
23716
24415
|
#hasSummaryHistory = false;
|
|
24416
|
+
#revisionPollPromise;
|
|
24417
|
+
#revisionSupported = false;
|
|
23717
24418
|
#liveEventSequences = /* @__PURE__ */ new Set();
|
|
23718
24419
|
#session;
|
|
23719
24420
|
#visibleState = "connecting";
|
|
@@ -23818,7 +24519,8 @@ var DshHostConnector = class {
|
|
|
23818
24519
|
...executionProfiles === void 0 ? {} : {
|
|
23819
24520
|
executionProfiles: cloneExecutionProfiles(executionProfiles)
|
|
23820
24521
|
},
|
|
23821
|
-
purpose: "execution"
|
|
24522
|
+
purpose: "execution",
|
|
24523
|
+
...this.#host.contextDeletionVersion === 1 ? { contextDeletionVersion: 1 } : {}
|
|
23822
24524
|
};
|
|
23823
24525
|
}
|
|
23824
24526
|
get executionRuntimeId() {
|
|
@@ -23851,6 +24553,7 @@ var DshHostConnector = class {
|
|
|
23851
24553
|
}
|
|
23852
24554
|
uploadLocalTurns() {
|
|
23853
24555
|
return this.#withLocalSyncControl(async () => {
|
|
24556
|
+
await this.#refreshContentRevision();
|
|
23854
24557
|
const before = this.localSyncStatus();
|
|
23855
24558
|
await this.#flushOutbox(true);
|
|
23856
24559
|
await this.#captureLocalTurns(0);
|
|
@@ -23873,6 +24576,15 @@ var DshHostConnector = class {
|
|
|
23873
24576
|
this.#started = true;
|
|
23874
24577
|
this.#automaticPolling = options.schedule !== false;
|
|
23875
24578
|
this.#notifyLifecycle("connecting");
|
|
24579
|
+
if (this.#host.onLiveOutput !== void 0) {
|
|
24580
|
+
this.#listenerDisposers.push(this.#host.onLiveOutput((event) => {
|
|
24581
|
+
const active = this.#state?.activeRequest;
|
|
24582
|
+
const output2 = this.#activeLiveOutput;
|
|
24583
|
+
if (this.#stopped || active === void 0 || output2 === void 0 || event.sourceSessionId !== output2.sourceSessionId || event.sourceSessionId !== (active.contextExecution?.sessionId ?? this.#host.sessionId))
|
|
24584
|
+
return;
|
|
24585
|
+
output2.mapper.onEvent(event);
|
|
24586
|
+
}));
|
|
24587
|
+
}
|
|
23876
24588
|
this.#listenerDisposers.push(this.#host.onSessionEvent((event) => {
|
|
23877
24589
|
const active = this.#state?.activeRequest;
|
|
23878
24590
|
if (active?.contextExecution !== void 0 && event.sourceSessionId !== active.contextExecution.sessionId)
|
|
@@ -23918,6 +24630,7 @@ var DshHostConnector = class {
|
|
|
23918
24630
|
}));
|
|
23919
24631
|
try {
|
|
23920
24632
|
const session = await this.#verifySessionBinding();
|
|
24633
|
+
this.#revisionSupported = session.contentRevision !== void 0;
|
|
23921
24634
|
this.#session = session;
|
|
23922
24635
|
this.#notifyLifecycle("connecting");
|
|
23923
24636
|
const storedState = await this.#stateStore.load();
|
|
@@ -23925,8 +24638,16 @@ var DshHostConnector = class {
|
|
|
23925
24638
|
throw new Error("GatherThread Session head precedes the persisted DSH cursor; refusing identity reuse");
|
|
23926
24639
|
}
|
|
23927
24640
|
const mode = await this.#host.open();
|
|
24641
|
+
if (storedState?.projectionSessionId && (storedState.contentRevision ?? 0) > 0) {
|
|
24642
|
+
if (!this.#host.resetCanonicalContext)
|
|
24643
|
+
throw new Error("DSH deletion-safe projection requires an updated native facade");
|
|
24644
|
+
const restored = await this.#host.resetCanonicalContext(storedState.contentRevision);
|
|
24645
|
+
if (restored.sessionId !== storedState.projectionSessionId)
|
|
24646
|
+
throw new Error("DSH restored another native projection");
|
|
24647
|
+
}
|
|
23928
24648
|
this.#state = this.#reconcileState(storedState, mode);
|
|
23929
24649
|
await this.#stateStore.save(this.#state);
|
|
24650
|
+
await this.#refreshContentRevision();
|
|
23930
24651
|
this.#runtime = await this.#api.registerRuntime(this.#runtimeRegistration());
|
|
23931
24652
|
this.#assertRuntime(this.#runtime);
|
|
23932
24653
|
this.#notifyLifecycle("idle");
|
|
@@ -23998,6 +24719,8 @@ var DshHostConnector = class {
|
|
|
23998
24719
|
stop() {
|
|
23999
24720
|
this.#stopPromise ??= (async () => {
|
|
24000
24721
|
this.#stopped = true;
|
|
24722
|
+
const liveOutput = this.#activeLiveOutput;
|
|
24723
|
+
this.#activeLiveOutput = void 0;
|
|
24001
24724
|
this.#notifyLifecycle("stopped");
|
|
24002
24725
|
this.#lifecycleAbort.abort(new Error("DSH connector stopped"));
|
|
24003
24726
|
if (this.#timer !== void 0) {
|
|
@@ -24011,6 +24734,7 @@ var DshHostConnector = class {
|
|
|
24011
24734
|
for (const dispose of this.#listenerDisposers.splice(0))
|
|
24012
24735
|
dispose();
|
|
24013
24736
|
await this.#host.dispose();
|
|
24737
|
+
void liveOutput?.mapper.finish(false).catch(() => void 0);
|
|
24014
24738
|
try {
|
|
24015
24739
|
await this.#pollPromise;
|
|
24016
24740
|
} catch {
|
|
@@ -24023,6 +24747,7 @@ var DshHostConnector = class {
|
|
|
24023
24747
|
return this.#stopPromise;
|
|
24024
24748
|
}
|
|
24025
24749
|
async #poll() {
|
|
24750
|
+
await this.#refreshContentRevision();
|
|
24026
24751
|
const state = this.#requireState();
|
|
24027
24752
|
if (state.activeRequest !== void 0) {
|
|
24028
24753
|
await this.#withExecutionPermit(() => this.#recoverActiveRequest());
|
|
@@ -24039,6 +24764,12 @@ var DshHostConnector = class {
|
|
|
24039
24764
|
let scanned = 0;
|
|
24040
24765
|
while (!this.#stopped) {
|
|
24041
24766
|
const page = await this.#api.readEvents(this.#config.sessionId, scanCursor, this.#config.pollLimit);
|
|
24767
|
+
if (page.contentRevision !== void 0)
|
|
24768
|
+
this.#revisionSupported = true;
|
|
24769
|
+
if ((page.contentRevision ?? 0) !== (state.contentRevision ?? 0)) {
|
|
24770
|
+
await this.#refreshContentRevision();
|
|
24771
|
+
return this.#poll();
|
|
24772
|
+
}
|
|
24042
24773
|
this.#validatePage(page.events, scanCursor);
|
|
24043
24774
|
const passive = [];
|
|
24044
24775
|
for (const event of page.events) {
|
|
@@ -24072,6 +24803,39 @@ var DshHostConnector = class {
|
|
|
24072
24803
|
}
|
|
24073
24804
|
throw new Error("DSH connector stopped during event replay");
|
|
24074
24805
|
}
|
|
24806
|
+
async #refreshContentRevision() {
|
|
24807
|
+
const state = this.#requireState();
|
|
24808
|
+
if (!this.#revisionSupported && (state.contentRevision ?? 0) === 0)
|
|
24809
|
+
return;
|
|
24810
|
+
const page = await this.#api.readEvents(this.#config.sessionId, 0, 1);
|
|
24811
|
+
const revision = page.contentRevision ?? 0;
|
|
24812
|
+
if (!Number.isSafeInteger(revision) || revision < (state.contentRevision ?? 0))
|
|
24813
|
+
throw new Error("Stale DSH shared context revision");
|
|
24814
|
+
if (revision === (state.contentRevision ?? 0)) {
|
|
24815
|
+
if (revision > 0 && state.projectionSessionId && this.#host.resetCanonicalContext) {
|
|
24816
|
+
const restored = await this.#host.resetCanonicalContext(revision);
|
|
24817
|
+
if (restored.sessionId !== state.projectionSessionId)
|
|
24818
|
+
throw new Error("DSH clean projection binding changed on reconnect");
|
|
24819
|
+
}
|
|
24820
|
+
return;
|
|
24821
|
+
}
|
|
24822
|
+
state.localOnlySessionIds = [.../* @__PURE__ */ new Set([...state.localOnlySessionIds ?? [], this.#config.dshSessionId, this.#host.sessionId])];
|
|
24823
|
+
state.outbox = [];
|
|
24824
|
+
delete state.activeRequest;
|
|
24825
|
+
this.#activeStatuses = [];
|
|
24826
|
+
this.#activeExecutionSelection = void 0;
|
|
24827
|
+
this.#summaryScanSequence = 0;
|
|
24828
|
+
this.#hasSummaryHistory = false;
|
|
24829
|
+
await this.#stateStore.save(state);
|
|
24830
|
+
if (this.#host.resetCanonicalContext) {
|
|
24831
|
+
const replacement = await this.#host.resetCanonicalContext(revision);
|
|
24832
|
+
state.projectionSessionId = replacement.sessionId;
|
|
24833
|
+
state.projectionCursor = 0;
|
|
24834
|
+
state.publishedDshSequence = this.#host.currentSequence();
|
|
24835
|
+
}
|
|
24836
|
+
state.contentRevision = revision;
|
|
24837
|
+
await this.#stateStore.save(state);
|
|
24838
|
+
}
|
|
24075
24839
|
async #executeRequest(request, selection) {
|
|
24076
24840
|
if (this.#stopped)
|
|
24077
24841
|
throw new Error("DSH connector stopped before claiming an Agent request");
|
|
@@ -24090,6 +24854,8 @@ var DshHostConnector = class {
|
|
|
24090
24854
|
await this.#projectCanonicalBatch([request], request.sequence);
|
|
24091
24855
|
return { claimed: false, completed: false };
|
|
24092
24856
|
}
|
|
24857
|
+
if ((claim2.contentRevision ?? state.contentRevision ?? 0) !== (state.contentRevision ?? 0))
|
|
24858
|
+
throw new Error("context_changed");
|
|
24093
24859
|
const quotedEvent = request.replyTo ? (await this.#readThroughRequest(request.id, request.sequence)).find((event) => event.id === request.replyTo) : void 0;
|
|
24094
24860
|
const prompt = buildDshRequestPrompt(request, quotedEvent);
|
|
24095
24861
|
const context = await this.#contextForRequest(request);
|
|
@@ -24102,6 +24868,7 @@ var DshHostConnector = class {
|
|
|
24102
24868
|
if (prepared !== void 0 && prepared.fromSequence !== baseline)
|
|
24103
24869
|
throw new Error("DSH context preparation returned an inconsistent sequence");
|
|
24104
24870
|
state.activeRequest = {
|
|
24871
|
+
contentRevision: state.contentRevision ?? 0,
|
|
24105
24872
|
requestId: request.id,
|
|
24106
24873
|
requestSequence: request.sequence,
|
|
24107
24874
|
dshFromSequence: baseline,
|
|
@@ -24115,7 +24882,7 @@ var DshHostConnector = class {
|
|
|
24115
24882
|
this.#activeExecutionSelection = selection;
|
|
24116
24883
|
this.#liveEventSequences.clear();
|
|
24117
24884
|
await this.#stateStore.save(state);
|
|
24118
|
-
const result = await this.#
|
|
24885
|
+
const result = await this.#promptWithLiveOutput(prompt, selection, prepared?.sessionId);
|
|
24119
24886
|
if (result.fromSequence !== baseline || result.toSequence < result.fromSequence) {
|
|
24120
24887
|
throw new Error("DSH Host prompt returned an inconsistent durable event range");
|
|
24121
24888
|
}
|
|
@@ -24137,7 +24904,7 @@ var DshHostConnector = class {
|
|
|
24137
24904
|
throw new Error("GatherThread history summary request has invalid source metadata");
|
|
24138
24905
|
if (selectedOnly)
|
|
24139
24906
|
this.#hasSummaryHistory = true;
|
|
24140
|
-
if (!selectedOnly && !await this.#sessionHasSummaryBefore(request.sequence))
|
|
24907
|
+
if (!selectedOnly && (this.#requireState().contentRevision ?? 0) === 0 && !await this.#sessionHasSummaryBefore(request.sequence))
|
|
24141
24908
|
return void 0;
|
|
24142
24909
|
if (!selectedOnly && this.#api.readContext === void 0) {
|
|
24143
24910
|
throw new Error("GatherThread summarized context is unavailable; update the connector before continuing");
|
|
@@ -24145,7 +24912,9 @@ var DshHostConnector = class {
|
|
|
24145
24912
|
if (this.#host.prepareContextExecution === void 0) {
|
|
24146
24913
|
throw new Error("DSH isolated context execution is unavailable; refusing to run a summary-aware request in native history");
|
|
24147
24914
|
}
|
|
24148
|
-
const received = selectedOnly ? { view: "original", through_sequence: request.sequence - 1, items: [] } : parseHistoryContext(await this.#api.readContext(this.#config.sessionId, void 0, request.sequence - 1), void 0, request.sequence - 1);
|
|
24915
|
+
const received = selectedOnly ? { view: "original", content_revision: this.#requireState().contentRevision ?? 0, through_sequence: request.sequence - 1, items: [] } : parseHistoryContext(await this.#api.readContext(this.#config.sessionId, void 0, request.sequence - 1), void 0, request.sequence - 1);
|
|
24916
|
+
if ((received.content_revision ?? 0) !== (this.#requireState().contentRevision ?? 0))
|
|
24917
|
+
throw new Error("context_changed");
|
|
24149
24918
|
const historyContext = { ...received, items: received.items.map((item) => ({ ...item, content: redactText(item.content) })) };
|
|
24150
24919
|
return { historyContext, selectedOnly };
|
|
24151
24920
|
}
|
|
@@ -24243,6 +25012,10 @@ var DshHostConnector = class {
|
|
|
24243
25012
|
throw new Error("Active GatherThread request no longer has a recoverable claim");
|
|
24244
25013
|
}
|
|
24245
25014
|
const claimAttempt = claim2.attemptCount ?? active.claimAttempt ?? 1;
|
|
25015
|
+
if ((active.contentRevision ?? 0) !== (state.contentRevision ?? 0) || (claim2.contentRevision ?? active.contentRevision ?? 0) !== (active.contentRevision ?? 0)) {
|
|
25016
|
+
await this.#retireFencedActiveRequest(state, active);
|
|
25017
|
+
return;
|
|
25018
|
+
}
|
|
24246
25019
|
active.claimAttempt = claimAttempt;
|
|
24247
25020
|
if (active.dshToSequence !== void 0) {
|
|
24248
25021
|
state.outbox = state.outbox.map((operation) => {
|
|
@@ -24315,7 +25088,7 @@ var DshHostConnector = class {
|
|
|
24315
25088
|
this.#activeStatuses = [];
|
|
24316
25089
|
this.#liveEventSequences.clear();
|
|
24317
25090
|
await this.#stateStore.save(state);
|
|
24318
|
-
const result = await this.#
|
|
25091
|
+
const result = await this.#promptWithLiveOutput(continuation, selection, execution?.sessionId);
|
|
24319
25092
|
if (result.fromSequence !== baseline || result.toSequence < result.fromSequence) {
|
|
24320
25093
|
throw new Error("DSH Host recovery prompt returned an inconsistent durable event range");
|
|
24321
25094
|
}
|
|
@@ -24344,6 +25117,94 @@ var DshHostConnector = class {
|
|
|
24344
25117
|
await this.#flushOutbox();
|
|
24345
25118
|
await this.#finalizeDeliveredRequest();
|
|
24346
25119
|
}
|
|
25120
|
+
async #promptWithLiveOutput(text, selection, executionSessionId) {
|
|
25121
|
+
const active = this.#requireState().activeRequest;
|
|
25122
|
+
if (active === void 0)
|
|
25123
|
+
throw new Error("No claimed DSH request owns live output");
|
|
25124
|
+
const requestId = active.requestId;
|
|
25125
|
+
const claimAttempt = active.claimAttempt ?? 1;
|
|
25126
|
+
const fromSequence = active.dshFromSequence;
|
|
25127
|
+
const runtime = this.#requireRuntime();
|
|
25128
|
+
const sourceSessionId = executionSessionId ?? this.#host.sessionId;
|
|
25129
|
+
const publisher = createLiveOutputPublisher({
|
|
25130
|
+
publish: async (update) => {
|
|
25131
|
+
const publication = this.#liveProgressPromise.then(async () => {
|
|
25132
|
+
const current = this.#state?.activeRequest;
|
|
25133
|
+
if (this.#stopped || this.#activeLiveOutput?.publisher !== publisher || current?.requestId !== requestId || (current.claimAttempt ?? 1) !== claimAttempt || current.dshFromSequence !== fromSequence || (current.contextExecution?.sessionId ?? this.#host.sessionId) !== sourceSessionId || this.#runtime?.id !== runtime.id || this.#activeExecutionSelection !== selection)
|
|
25134
|
+
return false;
|
|
25135
|
+
await this.#api.appendAgentProgress(this.#config.sessionId, requestId, {
|
|
25136
|
+
runtimeId: runtime.id,
|
|
25137
|
+
claimAttempt,
|
|
25138
|
+
contentRevision: active.contentRevision ?? 0,
|
|
25139
|
+
idempotencyKey: `${this.#config.deviceId}:${digest2(requestId).slice(0, 24)}:${claimAttempt}:live-${update.id}`,
|
|
25140
|
+
payload: { ...liveOutputPayload(update), capture_fidelity: "harness_transcript", source_harness: "deepseek-harness" },
|
|
25141
|
+
observedModel: selection.model,
|
|
25142
|
+
...selection.reasoningEffort === void 0 ? {} : { observedReasoningEffort: selection.reasoningEffort }
|
|
25143
|
+
});
|
|
25144
|
+
return true;
|
|
25145
|
+
});
|
|
25146
|
+
this.#liveProgressPromise = publication.then(() => void 0).catch((error62) => {
|
|
25147
|
+
this.#onBackgroundError?.(publicError(error62));
|
|
25148
|
+
});
|
|
25149
|
+
return publication.catch(() => false);
|
|
25150
|
+
}
|
|
25151
|
+
});
|
|
25152
|
+
const output2 = { publisher, mapper: createDshLiveEventMapper(publisher), sourceSessionId };
|
|
25153
|
+
this.#activeLiveOutput = output2;
|
|
25154
|
+
const abort = new AbortController();
|
|
25155
|
+
const abortLifecycle = () => abort.abort(this.#lifecycleAbort.signal.reason);
|
|
25156
|
+
this.#lifecycleAbort.signal.addEventListener("abort", abortLifecycle, { once: true });
|
|
25157
|
+
const verifyRevision = async () => {
|
|
25158
|
+
if (!this.#revisionSupported && (active.contentRevision ?? 0) === 0)
|
|
25159
|
+
return;
|
|
25160
|
+
try {
|
|
25161
|
+
const page = await this.#api.readEvents(this.#config.sessionId, 0, 1);
|
|
25162
|
+
if ((page.contentRevision ?? 0) !== (active.contentRevision ?? 0))
|
|
25163
|
+
abort.abort(new Error("context_changed"));
|
|
25164
|
+
} catch (error62) {
|
|
25165
|
+
abort.abort(error62);
|
|
25166
|
+
}
|
|
25167
|
+
};
|
|
25168
|
+
const timer = setInterval(() => {
|
|
25169
|
+
if (this.#revisionPollPromise)
|
|
25170
|
+
return;
|
|
25171
|
+
const poll = verifyRevision();
|
|
25172
|
+
this.#revisionPollPromise = poll;
|
|
25173
|
+
void poll.finally(() => {
|
|
25174
|
+
if (this.#revisionPollPromise === poll)
|
|
25175
|
+
this.#revisionPollPromise = void 0;
|
|
25176
|
+
});
|
|
25177
|
+
}, 1e3);
|
|
25178
|
+
timer.unref();
|
|
25179
|
+
try {
|
|
25180
|
+
await verifyRevision();
|
|
25181
|
+
abort.signal.throwIfAborted();
|
|
25182
|
+
const result = await this.#host.prompt(text, selection, executionSessionId, abort.signal);
|
|
25183
|
+
await verifyRevision();
|
|
25184
|
+
abort.signal.throwIfAborted();
|
|
25185
|
+
await output2.mapper.finish();
|
|
25186
|
+
return result;
|
|
25187
|
+
} catch (error62) {
|
|
25188
|
+
if (abort.signal.aborted) {
|
|
25189
|
+
const state = this.#requireState();
|
|
25190
|
+
state.outbox = state.outbox.filter((operation) => !outboxBelongsToRequest(operation, requestId));
|
|
25191
|
+
delete state.activeRequest;
|
|
25192
|
+
this.#activeExecutionSelection = void 0;
|
|
25193
|
+
await this.#stateStore.save(state);
|
|
25194
|
+
}
|
|
25195
|
+
throw error62;
|
|
25196
|
+
} finally {
|
|
25197
|
+
clearInterval(timer);
|
|
25198
|
+
this.#lifecycleAbort.signal.removeEventListener("abort", abortLifecycle);
|
|
25199
|
+
await this.#revisionPollPromise;
|
|
25200
|
+
if (this.#activeLiveOutput === output2)
|
|
25201
|
+
this.#activeLiveOutput = void 0;
|
|
25202
|
+
if (this.#stopped)
|
|
25203
|
+
void output2.mapper.finish(false).catch(() => void 0);
|
|
25204
|
+
else
|
|
25205
|
+
await output2.mapper.finish(false);
|
|
25206
|
+
}
|
|
25207
|
+
}
|
|
24347
25208
|
#queueLiveProgress(idSuffix, payload, throttle = true) {
|
|
24348
25209
|
const active = this.#state?.activeRequest;
|
|
24349
25210
|
const runtime = this.#runtime;
|
|
@@ -24353,6 +25214,9 @@ var DshHostConnector = class {
|
|
|
24353
25214
|
const claimAttempt = active.claimAttempt ?? 1;
|
|
24354
25215
|
const progressKey = `${requestId}:${String(claimAttempt)}`;
|
|
24355
25216
|
const now = Date.now();
|
|
25217
|
+
const streamedAt = this.#activeLiveOutput?.publisher.lastPublishedAt();
|
|
25218
|
+
if (throttle && streamedAt !== void 0 && now - streamedAt < LIVE_PROGRESS_MIN_INTERVAL_MS)
|
|
25219
|
+
return;
|
|
24356
25220
|
if (throttle && this.#lastLiveProgressKey === progressKey && now - this.#lastLiveProgressAt < LIVE_PROGRESS_MIN_INTERVAL_MS) {
|
|
24357
25221
|
return;
|
|
24358
25222
|
}
|
|
@@ -24363,7 +25227,7 @@ var DshHostConnector = class {
|
|
|
24363
25227
|
const idempotencyKey = `${this.#config.deviceId}:${digest2(requestId).slice(0, 24)}:${String(claimAttempt)}:${idSuffix}`;
|
|
24364
25228
|
this.#liveProgressPromise = this.#liveProgressPromise.then(async () => {
|
|
24365
25229
|
const current = this.#state?.activeRequest;
|
|
24366
|
-
if (current?.requestId !== requestId || (current.claimAttempt ?? 1) !== claimAttempt)
|
|
25230
|
+
if (this.#stopped || current?.requestId !== requestId || (current.claimAttempt ?? 1) !== claimAttempt || this.#runtime?.id !== runtime.id)
|
|
24367
25231
|
return;
|
|
24368
25232
|
const selection = this.#activeExecutionSelection;
|
|
24369
25233
|
if (selection === void 0)
|
|
@@ -24371,6 +25235,7 @@ var DshHostConnector = class {
|
|
|
24371
25235
|
await this.#api.appendAgentProgress(this.#config.sessionId, requestId, {
|
|
24372
25236
|
runtimeId: runtime.id,
|
|
24373
25237
|
claimAttempt,
|
|
25238
|
+
contentRevision: active.contentRevision ?? 0,
|
|
24374
25239
|
idempotencyKey,
|
|
24375
25240
|
payload,
|
|
24376
25241
|
observedModel: selection.model,
|
|
@@ -24388,11 +25253,15 @@ var DshHostConnector = class {
|
|
|
24388
25253
|
}
|
|
24389
25254
|
async #projectCanonicalBatch(events, throughSequence) {
|
|
24390
25255
|
const state = this.#requireState();
|
|
25256
|
+
if (state.localOnlySessionIds?.includes(this.#host.sessionId))
|
|
25257
|
+
return;
|
|
24391
25258
|
if (throughSequence <= state.projectionCursor)
|
|
24392
25259
|
return;
|
|
24393
25260
|
const runtime = this.#requireRuntime();
|
|
24394
25261
|
const projections = [];
|
|
24395
25262
|
for (const event of events) {
|
|
25263
|
+
if (event.deleted)
|
|
25264
|
+
continue;
|
|
24396
25265
|
if (event.type === "agent_request" && asObject3(event.payload)?.history_summary !== void 0) {
|
|
24397
25266
|
this.#hasSummaryHistory = true;
|
|
24398
25267
|
continue;
|
|
@@ -24437,6 +25306,8 @@ var DshHostConnector = class {
|
|
|
24437
25306
|
}
|
|
24438
25307
|
async #captureLocalTurns(basedOnSequence) {
|
|
24439
25308
|
const state = this.#requireState();
|
|
25309
|
+
if (state.localOnlySessionIds?.includes(this.#host.sessionId))
|
|
25310
|
+
return;
|
|
24440
25311
|
if (state.activeRequest !== void 0 || state.outbox.length > 0)
|
|
24441
25312
|
return;
|
|
24442
25313
|
const current = this.#host.currentSequence();
|
|
@@ -24453,6 +25324,7 @@ var DshHostConnector = class {
|
|
|
24453
25324
|
input: {
|
|
24454
25325
|
localTurnId: turn.localTurnId,
|
|
24455
25326
|
runtimeId: runtime.id,
|
|
25327
|
+
contentRevision: state.contentRevision ?? 0,
|
|
24456
25328
|
basedOnSequence: basedOnSequence ?? state.serverCursor,
|
|
24457
25329
|
occurredAt: turn.occurredAt,
|
|
24458
25330
|
observedModel: this.#config.model,
|
|
@@ -24566,7 +25438,10 @@ var DshHostConnector = class {
|
|
|
24566
25438
|
}
|
|
24567
25439
|
}
|
|
24568
25440
|
});
|
|
24569
|
-
return operations
|
|
25441
|
+
return operations.map((operation) => ({
|
|
25442
|
+
...operation,
|
|
25443
|
+
input: { ...operation.input, contentRevision: this.#requireState().activeRequest?.contentRevision ?? 0 }
|
|
25444
|
+
}));
|
|
24570
25445
|
}
|
|
24571
25446
|
async #flushOutbox(includeLocalTurns = true) {
|
|
24572
25447
|
const state = this.#requireState();
|
|
@@ -24575,6 +25450,11 @@ var DshHostConnector = class {
|
|
|
24575
25450
|
const operation = state.outbox[0];
|
|
24576
25451
|
if (operation === void 0)
|
|
24577
25452
|
break;
|
|
25453
|
+
if ((operation.input.contentRevision ?? 0) !== (state.contentRevision ?? 0) || operation.kind === "local_turn" && state.localOnlySessionIds?.includes(this.#host.sessionId)) {
|
|
25454
|
+
state.outbox.shift();
|
|
25455
|
+
await this.#stateStore.save(state);
|
|
25456
|
+
continue;
|
|
25457
|
+
}
|
|
24578
25458
|
if (operation.kind === "local_turn" && !includeLocalTurns)
|
|
24579
25459
|
break;
|
|
24580
25460
|
if (operation.input.runtimeId !== runtime.id) {
|
|
@@ -24909,6 +25789,8 @@ function captureCompletedLocalTurns(events, fromSequence, dshSessionId) {
|
|
|
24909
25789
|
return { turns, safeThroughSequence };
|
|
24910
25790
|
}
|
|
24911
25791
|
function hasCompletedDshLocalTurn(events, dshSessionId) {
|
|
25792
|
+
if (events.some((event) => event.type === "user/message" && /^gatherthread-retired:[0-9]+$/.test(String(asObject3(event.data)?.id)) && asObject3(asObject3(event.data)?.source)?.plugin === "gatherthread"))
|
|
25793
|
+
return false;
|
|
24912
25794
|
return captureCompletedLocalTurns(events, 0, dshSessionId).turns.length > 0;
|
|
24913
25795
|
}
|
|
24914
25796
|
function isDirectLocalUserMessage(event) {
|
|
@@ -24979,16 +25861,16 @@ function asObject3(value) {
|
|
|
24979
25861
|
}
|
|
24980
25862
|
|
|
24981
25863
|
// dist/src/dsh-compat.js
|
|
24982
|
-
import { createHash as createHash7 } from "node:crypto";
|
|
25864
|
+
import { createHash as createHash7, randomUUID as randomUUID5 } from "node:crypto";
|
|
24983
25865
|
var DSH_COMPATIBILITY = Object.freeze({
|
|
24984
|
-
tag: "dsh-v0.1.
|
|
24985
|
-
version: "0.1.
|
|
24986
|
-
commit: "
|
|
25866
|
+
tag: "dsh-v0.1.7-rc.2",
|
|
25867
|
+
version: "0.1.7-rc.2",
|
|
25868
|
+
commit: "477b4f420553e8a52c2fbccc464d7561b239c443",
|
|
24987
25869
|
profile: "headless"
|
|
24988
25870
|
});
|
|
24989
25871
|
var DSH_NPM_COMPATIBILITY = Object.freeze({
|
|
24990
25872
|
package: "@deepseek-ai/dsh",
|
|
24991
|
-
version: "0.1.
|
|
25873
|
+
version: "0.1.7-rc.2",
|
|
24992
25874
|
profile: "web",
|
|
24993
25875
|
persistenceProbe: "list"
|
|
24994
25876
|
});
|
|
@@ -25018,16 +25900,19 @@ function createDshHostFacade(options) {
|
|
|
25018
25900
|
const sessionTitle = options.sessionTitle === void 0 ? void 0 : requireService(context, "sessionTitle", ["rename"]);
|
|
25019
25901
|
const workspaceRegistry = options.workspaceTitle === void 0 ? void 0 : requireService(context, "workspaceRegistry", ["create"]);
|
|
25020
25902
|
const eventSubscribers = /* @__PURE__ */ new Set();
|
|
25903
|
+
const liveSubscribers = /* @__PURE__ */ new Set();
|
|
25021
25904
|
const statusSubscribers = /* @__PURE__ */ new Set();
|
|
25022
25905
|
const listenerDisposers = [];
|
|
25023
25906
|
const lifecycleAbort = new AbortController();
|
|
25024
25907
|
let handle;
|
|
25025
25908
|
let executionHandle;
|
|
25026
|
-
let
|
|
25909
|
+
let nativeSessionId = options.sessionId;
|
|
25910
|
+
let contentRevision = 0;
|
|
25911
|
+
let contextOperationPromise;
|
|
25027
25912
|
const executionBinding = JSON.stringify({ nativeSessionId: options.sessionId, ...options.contextBinding });
|
|
25028
|
-
|
|
25029
|
-
|
|
25030
|
-
|
|
25913
|
+
let executionSessionId = `gatherthread-execution-${createHash7("sha256").update(executionBinding).digest("hex").slice(0, 32)}`;
|
|
25914
|
+
let executionOwnerId = `gatherthread-execution-owner:${createHash7("sha256").update(executionBinding).digest("hex")}`;
|
|
25915
|
+
let executionOwnerText = JSON.stringify({
|
|
25031
25916
|
version: 1,
|
|
25032
25917
|
owner: "gatherthread",
|
|
25033
25918
|
native_session_id: options.sessionId,
|
|
@@ -25040,19 +25925,76 @@ function createDshHostFacade(options) {
|
|
|
25040
25925
|
let knownProjectionMessageIds;
|
|
25041
25926
|
let disposePromise;
|
|
25042
25927
|
let disposed = false;
|
|
25928
|
+
let livePrompt;
|
|
25929
|
+
const emitLive = (owner, event) => {
|
|
25930
|
+
if (disposed || livePrompt !== owner || owner.closed)
|
|
25931
|
+
return;
|
|
25932
|
+
for (const subscriber of liveSubscribers)
|
|
25933
|
+
subscriber(event);
|
|
25934
|
+
};
|
|
25043
25935
|
listenerDisposers.push(context.on("session/event", (...args) => {
|
|
25044
25936
|
const session = asSession(args[0]);
|
|
25045
25937
|
const event = asSessionEvent(args[1]);
|
|
25046
|
-
if (session === void 0 || session.id !==
|
|
25938
|
+
if (session === void 0 || session.id !== nativeSessionId && session.id !== executionHandle?.agent.session.id || event === void 0)
|
|
25047
25939
|
return;
|
|
25048
25940
|
for (const subscriber of eventSubscribers)
|
|
25049
25941
|
subscriber({ ...event, sourceSessionId: session.id });
|
|
25942
|
+
const owner = livePrompt;
|
|
25943
|
+
if (owner === void 0 || owner.closed || session !== owner.agent.session)
|
|
25944
|
+
return;
|
|
25945
|
+
const data = asObject4(event.data);
|
|
25946
|
+
if (event.type === "turn/start" && owner.turn === void 0 && Number.isSafeInteger(data?.turn)) {
|
|
25947
|
+
owner.turn = Number(data.turn);
|
|
25948
|
+
}
|
|
25949
|
+
if (owner.turn === void 0 || data?.turn !== void 0 && data.turn !== owner.turn)
|
|
25950
|
+
return;
|
|
25951
|
+
if (event.type === "step/start" && Number.isSafeInteger(data?.step))
|
|
25952
|
+
owner.step = Number(data.step);
|
|
25953
|
+
if (["assistant/message", "assistant/attempt", "tool/call", "tool/result", "todo/write"].includes(event.type)) {
|
|
25954
|
+
emitLive(owner, { kind: "session-event", sourceSessionId: session.id, event });
|
|
25955
|
+
}
|
|
25956
|
+
if (event.type === "turn/end")
|
|
25957
|
+
owner.closed = true;
|
|
25958
|
+
}, { global: true }));
|
|
25959
|
+
listenerDisposers.push(context.on("agent/assistant-stream", (...args) => {
|
|
25960
|
+
const owner = livePrompt;
|
|
25961
|
+
const payload = asObject4(args[0]);
|
|
25962
|
+
if (owner === void 0 || !owner.nativeFrames || owner.turn === void 0 || payload?.agent !== owner.agent)
|
|
25963
|
+
return;
|
|
25964
|
+
const frame = parseDshAssistantStreamFrame(payload.frame);
|
|
25965
|
+
if (frame === void 0 || frame.type === "start" && frame.turn !== owner.turn)
|
|
25966
|
+
return;
|
|
25967
|
+
emitLive(owner, { kind: "assistant-stream", sourceSessionId: owner.agent.session.id, frame });
|
|
25968
|
+
}, { global: true }));
|
|
25969
|
+
listenerDisposers.push(context.on("llm/stream", (...args) => {
|
|
25970
|
+
const request = asObject4(args[0]);
|
|
25971
|
+
const next = args[1];
|
|
25972
|
+
if (typeof next !== "function")
|
|
25973
|
+
return;
|
|
25974
|
+
const stream = next();
|
|
25975
|
+
const owner = livePrompt;
|
|
25976
|
+
if (owner === void 0 || owner.nativeFrames || owner.closed || owner.turn === void 0 || owner.step === void 0 || owner.isLoopRequest === void 0 || request === void 0 || !Object.isFrozen(args[0]) || request.sessionId !== owner.agent.session.id || request.provider !== owner.provider || request.model !== owner.model || typeof agents.get !== "function" || agents.get(owner.agent.session.id) !== owner.agent || !owner.isLoopRequest(args[0]))
|
|
25977
|
+
return stream;
|
|
25978
|
+
const attemptId = randomUUID5();
|
|
25979
|
+
const publish = (frame) => emitLive(owner, {
|
|
25980
|
+
kind: "assistant-stream",
|
|
25981
|
+
sourceSessionId: owner.agent.session.id,
|
|
25982
|
+
frame
|
|
25983
|
+
});
|
|
25984
|
+
return (async function* () {
|
|
25985
|
+
let index = 0;
|
|
25986
|
+
publish({ type: "start", attemptId, revision: ++owner.revision, turn: owner.turn, step: owner.step });
|
|
25987
|
+
for await (const chunk of stream) {
|
|
25988
|
+
publish({ type: "chunk", attemptId, revision: ++owner.revision, index: index++, time: Date.now(), chunk });
|
|
25989
|
+
yield chunk;
|
|
25990
|
+
}
|
|
25991
|
+
})();
|
|
25050
25992
|
}, { global: true }));
|
|
25051
25993
|
listenerDisposers.push(context.on("agent/status", (...args) => {
|
|
25052
25994
|
const payload = asObject4(args[0]);
|
|
25053
25995
|
const agent = payload ? asAgent(payload.agent) : void 0;
|
|
25054
25996
|
const status = payload?.status;
|
|
25055
|
-
if (agent === void 0 || agent.session.id !==
|
|
25997
|
+
if (agent === void 0 || agent.session.id !== nativeSessionId && agent.session.id !== executionHandle?.agent.session.id || status !== "running" && status !== "idle")
|
|
25056
25998
|
return;
|
|
25057
25999
|
for (const subscriber of statusSubscribers)
|
|
25058
26000
|
subscriber(status, agent.session.id);
|
|
@@ -25064,7 +26006,7 @@ function createDshHostFacade(options) {
|
|
|
25064
26006
|
await releaseHandle();
|
|
25065
26007
|
throw new Error("DSH host facade was disposed during open");
|
|
25066
26008
|
}
|
|
25067
|
-
if (acquired.agent.session.id !==
|
|
26009
|
+
if (acquired.agent.session.id !== nativeSessionId) {
|
|
25068
26010
|
await releaseHandle();
|
|
25069
26011
|
throw new Error("DSH Host returned an agent for an unexpected Session identity");
|
|
25070
26012
|
}
|
|
@@ -25091,13 +26033,13 @@ function createDshHostFacade(options) {
|
|
|
25091
26033
|
const parent = requireAgent(handle);
|
|
25092
26034
|
if (parent.status !== "idle")
|
|
25093
26035
|
throw new Error("Native DSH Agent must be idle before isolated context execution");
|
|
25094
|
-
if (parent.session.header?.cwd !== options.workspacePath || agents.get?.(
|
|
26036
|
+
if (parent.session.header?.cwd !== options.workspacePath || agents.get?.(nativeSessionId) !== parent) {
|
|
25095
26037
|
throw new Error("Native DSH workspace or live owner does not match the isolated context binding");
|
|
25096
26038
|
}
|
|
25097
26039
|
};
|
|
25098
26040
|
const assertExecutionOwnership = (agent) => {
|
|
25099
26041
|
const session = agent.session;
|
|
25100
|
-
if (session.id !== executionSessionId || session.header?.cwd !== options.workspacePath || session.header.parentSession !==
|
|
26042
|
+
if (session.id !== executionSessionId || session.header?.cwd !== options.workspacePath || session.header.parentSession !== nativeSessionId || session.header.origin !== "subagent") {
|
|
25101
26043
|
throw new Error("DSH isolated execution Session ownership does not match this native binding");
|
|
25102
26044
|
}
|
|
25103
26045
|
if (agents.get !== void 0 && agents.get(executionSessionId) !== agent) {
|
|
@@ -25118,6 +26060,118 @@ function createDshHostFacade(options) {
|
|
|
25118
26060
|
throw new Error("DSH isolated execution Session contains local manual input; refusing to replace or execute it");
|
|
25119
26061
|
}
|
|
25120
26062
|
};
|
|
26063
|
+
const recordedRevision = (session) => session.snapshotEvents(0).reduce((highest, value) => {
|
|
26064
|
+
const event = asObject4(value), data = asObject4(event?.data);
|
|
26065
|
+
const id = data?.id;
|
|
26066
|
+
if (event?.type !== "user/message" || typeof id !== "string" || !/^gatherthread-retired:[0-9]+$/.test(id) || asObject4(data?.source)?.kind !== "plugin" || asObject4(data?.source)?.plugin !== "gatherthread")
|
|
26067
|
+
return highest;
|
|
26068
|
+
const revision = Number(id.slice("gatherthread-retired:".length));
|
|
26069
|
+
return Number.isSafeInteger(revision) ? Math.max(highest, revision) : highest;
|
|
26070
|
+
}, 0);
|
|
26071
|
+
const resetCanonicalContext = async (revision) => {
|
|
26072
|
+
if (!Number.isSafeInteger(revision) || revision < 1 || revision < contentRevision)
|
|
26073
|
+
throw new Error("Stale DSH content revision");
|
|
26074
|
+
if (options.contextBinding === void 0 || Object.values(options.contextBinding).some((value) => !value) || typeof agents.get !== "function")
|
|
26075
|
+
throw new Error("DSH context reset requires an explicit owned GatherThread binding");
|
|
26076
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26077
|
+
await open7();
|
|
26078
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26079
|
+
if (promptActive || projectionActive)
|
|
26080
|
+
throw new Error("Wait for the active DSH turn before replacing its projection");
|
|
26081
|
+
const parent = requireAgent(handle);
|
|
26082
|
+
if (revision < recordedRevision(parent.session))
|
|
26083
|
+
throw new Error("Retired DSH revision cannot resume");
|
|
26084
|
+
assertExecutionParentIdle();
|
|
26085
|
+
const targetId = `gatherthread-projection-${createHash7("sha256").update(`${executionBinding}:${revision}`).digest("hex").slice(0, 32)}`;
|
|
26086
|
+
if (nativeSessionId === targetId && contentRevision === revision)
|
|
26087
|
+
return { sessionId: targetId };
|
|
26088
|
+
const ownerId = `gatherthread-projection-owner:${createHash7("sha256").update(`${executionBinding}:${revision}`).digest("hex")}`;
|
|
26089
|
+
const ownerText = JSON.stringify({ version: 1, binding: options.contextBinding, native_session_id: options.sessionId, content_revision: revision });
|
|
26090
|
+
projectionActive = true;
|
|
26091
|
+
let candidate;
|
|
26092
|
+
try {
|
|
26093
|
+
const retired = await createIsolatedMessage(`gatherthread-retired:${revision}`, "GatherThread retired this context. Continue here locally only.", options);
|
|
26094
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26095
|
+
if (recordedRevision(parent.session) < revision) {
|
|
26096
|
+
parent.session.append("user/message", retired, { surfaceOp: "append" });
|
|
26097
|
+
await sessions.flush(parent.session);
|
|
26098
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26099
|
+
}
|
|
26100
|
+
if (agents.get?.(targetId) !== void 0)
|
|
26101
|
+
throw new Error("DSH clean projection already has another live owner");
|
|
26102
|
+
const stored = await hasPersistedSession(persistence, targetId, lifecycleAbort.signal);
|
|
26103
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26104
|
+
const presets = asObject4(context.get("agentPresets"));
|
|
26105
|
+
const setup = (ctx) => {
|
|
26106
|
+
if (presets !== void 0) {
|
|
26107
|
+
if (typeof presets.composeFrom !== "function" || typeof presets.composedPreset !== "function")
|
|
26108
|
+
throw new Error("Native DSH tool inheritance unavailable");
|
|
26109
|
+
const expected = presets.composedPreset(parent.ctx);
|
|
26110
|
+
if (presets.composeFrom(ctx, parent.ctx) !== expected)
|
|
26111
|
+
throw new Error("DSH clean projection did not inherit native tools");
|
|
26112
|
+
}
|
|
26113
|
+
};
|
|
26114
|
+
candidate = await (stored ? agents.resume({
|
|
26115
|
+
resumeSessionId: targetId,
|
|
26116
|
+
agentOptions: { provider: options.provider, model: options.model },
|
|
26117
|
+
signal: lifecycleAbort.signal,
|
|
26118
|
+
setup
|
|
26119
|
+
}) : agents.create({
|
|
26120
|
+
sessionId: targetId,
|
|
26121
|
+
meta: { cwd: options.workspacePath, parentSession: options.sessionId, origin: "subagent" },
|
|
26122
|
+
agentOptions: { provider: options.provider, model: options.model },
|
|
26123
|
+
signal: lifecycleAbort.signal,
|
|
26124
|
+
setup
|
|
26125
|
+
}));
|
|
26126
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26127
|
+
const agent = candidate.agent;
|
|
26128
|
+
if (agent.session.id !== targetId || agent.session.header?.cwd !== options.workspacePath || agent.status !== "idle" || agent.session.header.parentSession !== options.sessionId || agent.session.header.origin !== "subagent" || agents.get?.(targetId) !== agent)
|
|
26129
|
+
throw new Error("DSH clean projection ownership is invalid");
|
|
26130
|
+
if (!stored) {
|
|
26131
|
+
if (agent.session.seq !== 0)
|
|
26132
|
+
throw new Error("DSH clean projection is not fresh");
|
|
26133
|
+
const owner = await createIsolatedMessage(ownerId, ownerText, options);
|
|
26134
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26135
|
+
agent.session.append("user/message", owner, { surfaceOp: "append" });
|
|
26136
|
+
}
|
|
26137
|
+
const events = agent.session.snapshotEvents(0).map(asObject4);
|
|
26138
|
+
if (!events.some((event) => {
|
|
26139
|
+
const data = asObject4(event?.data), source = asObject4(data?.source);
|
|
26140
|
+
return event?.type === "user/message" && data?.id === ownerId && source?.kind === "plugin" && source.plugin === "gatherthread" && Array.isArray(data?.content) && data.content.length === 1 && asObject4(data.content[0])?.text === ownerText;
|
|
26141
|
+
})) {
|
|
26142
|
+
throw new Error("DSH clean projection is missing its durable owner marker");
|
|
26143
|
+
}
|
|
26144
|
+
await sessions.flush(agent.session);
|
|
26145
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26146
|
+
if (sessionTitle && options.sessionTitle) {
|
|
26147
|
+
await sessionTitle.rename(agent.session, options.sessionTitle);
|
|
26148
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26149
|
+
}
|
|
26150
|
+
if (workspaceRegistry && options.workspaceTitle) {
|
|
26151
|
+
const workspace = await workspaceRegistry.create(options.workspacePath, options.workspaceTitle);
|
|
26152
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26153
|
+
await workspace.attachSession(targetId);
|
|
26154
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26155
|
+
}
|
|
26156
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26157
|
+
await releaseExecutionHandle();
|
|
26158
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26159
|
+
await releaseHandle();
|
|
26160
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26161
|
+
handle = candidate;
|
|
26162
|
+
candidate = void 0;
|
|
26163
|
+
nativeSessionId = targetId;
|
|
26164
|
+
contentRevision = revision;
|
|
26165
|
+
knownProjectionMessageIds = void 0;
|
|
26166
|
+
return { sessionId: targetId };
|
|
26167
|
+
} finally {
|
|
26168
|
+
try {
|
|
26169
|
+
await candidate?.dispose();
|
|
26170
|
+
} finally {
|
|
26171
|
+
projectionActive = false;
|
|
26172
|
+
}
|
|
26173
|
+
}
|
|
26174
|
+
};
|
|
25121
26175
|
const prepareContextExecution = async (input2) => {
|
|
25122
26176
|
if (disposed)
|
|
25123
26177
|
throw new Error("DSH host facade is disposed");
|
|
@@ -25138,6 +26192,30 @@ function createDshHostFacade(options) {
|
|
|
25138
26192
|
if (disposed || promptActive || projectionActive)
|
|
25139
26193
|
throw new Error("DSH host facade permits only one active write");
|
|
25140
26194
|
const parent = requireAgent(handle);
|
|
26195
|
+
const revision = historyContext.content_revision ?? 0;
|
|
26196
|
+
if (revision < Math.max(contentRevision, recordedRevision(parent.session)))
|
|
26197
|
+
throw new Error("Stale retired DSH context revision");
|
|
26198
|
+
if (revision !== contentRevision || revision > 0 && !executionSessionId.endsWith(createHash7("sha256").update(`${executionBinding}:${revision}`).digest("hex").slice(0, 32))) {
|
|
26199
|
+
await releaseExecutionHandle();
|
|
26200
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26201
|
+
contentRevision = revision;
|
|
26202
|
+
const binding = `${executionBinding}:${revision}`;
|
|
26203
|
+
executionSessionId = `gatherthread-execution-${createHash7("sha256").update(binding).digest("hex").slice(0, 32)}`;
|
|
26204
|
+
executionOwnerId = `gatherthread-execution-owner:${createHash7("sha256").update(binding).digest("hex")}`;
|
|
26205
|
+
executionOwnerText = JSON.stringify({
|
|
26206
|
+
version: 1,
|
|
26207
|
+
owner: "gatherthread",
|
|
26208
|
+
native_session_id: options.sessionId,
|
|
26209
|
+
execution_session_id: executionSessionId,
|
|
26210
|
+
binding: options.contextBinding,
|
|
26211
|
+
content_revision: revision
|
|
26212
|
+
});
|
|
26213
|
+
const marker = await createIsolatedMessage(`gatherthread-retired:${revision}`, "GatherThread previous execution context is local only.", options);
|
|
26214
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26215
|
+
parent.session.append("user/message", marker, { surfaceOp: "append" });
|
|
26216
|
+
await sessions.flush(parent.session);
|
|
26217
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
26218
|
+
}
|
|
25141
26219
|
assertExecutionParentIdle();
|
|
25142
26220
|
const presets = asObject4(context.get("agentPresets"));
|
|
25143
26221
|
let parentPreset;
|
|
@@ -25146,7 +26224,8 @@ function createDshHostFacade(options) {
|
|
|
25146
26224
|
throw new Error("Pinned DSH public preset inheritance API is unavailable; refusing an isolated Agent without native tools");
|
|
25147
26225
|
}
|
|
25148
26226
|
parentPreset = presets.composedPreset(parent.ctx);
|
|
25149
|
-
|
|
26227
|
+
const roots = Array.isArray(presets.roots) ? presets.roots : void 0;
|
|
26228
|
+
if (parentPreset === void 0 && roots !== void 0 && roots.length > 0) {
|
|
25150
26229
|
throw new Error("Native DSH Agent has no composed preset; restore its tool composition before using summarized context");
|
|
25151
26230
|
}
|
|
25152
26231
|
}
|
|
@@ -25180,7 +26259,7 @@ function createDshHostFacade(options) {
|
|
|
25180
26259
|
sessionId: executionSessionId,
|
|
25181
26260
|
meta: {
|
|
25182
26261
|
cwd: options.workspacePath,
|
|
25183
|
-
parentSession:
|
|
26262
|
+
parentSession: nativeSessionId,
|
|
25184
26263
|
origin: "subagent",
|
|
25185
26264
|
...parentPreset === void 0 ? {} : { agentPreset: parentPreset }
|
|
25186
26265
|
},
|
|
@@ -25194,7 +26273,7 @@ function createDshHostFacade(options) {
|
|
|
25194
26273
|
}
|
|
25195
26274
|
const agent2 = operationAgent(executionSessionId);
|
|
25196
26275
|
if (!stored) {
|
|
25197
|
-
if (agent2.session.id !== executionSessionId || agent2.session.seq !== 0 || agent2.session.header?.parentSession !==
|
|
26276
|
+
if (agent2.session.id !== executionSessionId || agent2.session.seq !== 0 || agent2.session.header?.parentSession !== nativeSessionId || agent2.session.header.origin !== "subagent" || agent2.session.header.cwd !== options.workspacePath || agent2.status !== "idle") {
|
|
25198
26277
|
throw new Error("DSH did not create a fresh, owned isolated execution Session");
|
|
25199
26278
|
}
|
|
25200
26279
|
const ownerMessage = await createIsolatedMessage(executionOwnerId, executionOwnerText, options);
|
|
@@ -25230,7 +26309,7 @@ ${JSON.stringify(historyContext.items)}`;
|
|
|
25230
26309
|
const nodes = agent.session.surface?.nodes;
|
|
25231
26310
|
if (!Array.isArray(nodes) || nodes.some((seq) => !Number.isSafeInteger(seq) || seq < 0 || seq >= agent.session.seq) || new Set(nodes).size !== nodes.length)
|
|
25232
26311
|
throw new Error("Pinned DSH public Session surface API is unavailable or invalid");
|
|
25233
|
-
agent.session.append("user/message", message, nodes.length === 0 ? { surfaceOp: "append" } : { surfaceOp: { op: "replace",
|
|
26312
|
+
agent.session.append("user/message", message, nodes.length === 0 ? { surfaceOp: "append" } : { surfaceOp: { op: "replace", startSeq: nodes[0], endSeq: nodes.at(-1) }, sourceEventSeqs: [...nodes] });
|
|
25234
26313
|
}
|
|
25235
26314
|
await sessions.flush(agent.session);
|
|
25236
26315
|
throwIfDisposed(disposed, lifecycleAbort.signal, "projection");
|
|
@@ -25239,11 +26318,11 @@ ${JSON.stringify(historyContext.items)}`;
|
|
|
25239
26318
|
projectionActive = false;
|
|
25240
26319
|
}
|
|
25241
26320
|
};
|
|
25242
|
-
const setupNativeAgent = async (agentContext) => {
|
|
26321
|
+
const setupNativeAgent = async (agentContext, agentValue) => {
|
|
25243
26322
|
const presets = asObject4(context.get("agentPresets"));
|
|
25244
26323
|
if (presets === void 0 || Array.isArray(presets.roots) && presets.roots.length === 0)
|
|
25245
26324
|
return;
|
|
25246
|
-
const agent = asAgent(
|
|
26325
|
+
const agent = asAgent(agentValue);
|
|
25247
26326
|
const projections = asObject4(context.get("sessionProjections"));
|
|
25248
26327
|
if (agent === void 0 || typeof presets.mount !== "function" || typeof projections?.stateOf !== "function") {
|
|
25249
26328
|
throw new Error("Pinned DSH public native preset composition API is unavailable");
|
|
@@ -25346,7 +26425,8 @@ ${JSON.stringify(historyContext.items)}`;
|
|
|
25346
26425
|
return parsed;
|
|
25347
26426
|
});
|
|
25348
26427
|
};
|
|
25349
|
-
const prompt = async (text, requestedSelection, requestedExecutionId) => {
|
|
26428
|
+
const prompt = async (text, requestedSelection, requestedExecutionId, signal) => {
|
|
26429
|
+
signal?.throwIfAborted();
|
|
25350
26430
|
if (disposed)
|
|
25351
26431
|
throw new Error("DSH host facade is disposed");
|
|
25352
26432
|
if (!text.trim())
|
|
@@ -25361,11 +26441,15 @@ ${JSON.stringify(historyContext.items)}`;
|
|
|
25361
26441
|
promptActive = true;
|
|
25362
26442
|
let disposeSelection;
|
|
25363
26443
|
let selectionRef;
|
|
26444
|
+
let abortPrompt;
|
|
25364
26445
|
try {
|
|
25365
26446
|
if (requestedExecutionId === void 0)
|
|
25366
26447
|
await open7();
|
|
25367
26448
|
throwIfDisposed(disposed, lifecycleAbort.signal, "prompt");
|
|
25368
26449
|
const agent = operationAgent(requestedExecutionId);
|
|
26450
|
+
signal?.throwIfAborted();
|
|
26451
|
+
if (signal && typeof agent.cancel !== "function")
|
|
26452
|
+
throw new Error("DSH public cancel API is required for deletion-safe execution");
|
|
25369
26453
|
if (requestedExecutionId !== void 0) {
|
|
25370
26454
|
assertExecutionParentIdle();
|
|
25371
26455
|
assertExecutionOwnership(agent);
|
|
@@ -25391,8 +26475,41 @@ ${JSON.stringify(historyContext.items)}`;
|
|
|
25391
26475
|
assertExecutionParentIdle();
|
|
25392
26476
|
assertExecutionOwnership(agent);
|
|
25393
26477
|
}
|
|
26478
|
+
if (liveSubscribers.size > 0) {
|
|
26479
|
+
let imported;
|
|
26480
|
+
try {
|
|
26481
|
+
imported = asObject4(await (options.moduleImporter ?? importDshModule)(USER_MESSAGE_MODULE));
|
|
26482
|
+
} catch {
|
|
26483
|
+
}
|
|
26484
|
+
throwIfDisposed(disposed, lifecycleAbort.signal, "prompt");
|
|
26485
|
+
if (agent.status !== "idle" || agent.session.seq !== fromSequence)
|
|
26486
|
+
throw new Error("DSH Agent changed while preparing live output");
|
|
26487
|
+
livePrompt = {
|
|
26488
|
+
agent,
|
|
26489
|
+
closed: false,
|
|
26490
|
+
revision: 0,
|
|
26491
|
+
nativeFrames: typeof imported?.expandAssistantStream === "function",
|
|
26492
|
+
...typeof imported?.isAgentLoopRequest === "function" ? { isLoopRequest: imported.isAgentLoopRequest } : {},
|
|
26493
|
+
provider: requestedSelection?.provider ?? options.provider,
|
|
26494
|
+
model: requestedSelection?.model ?? options.model
|
|
26495
|
+
};
|
|
26496
|
+
}
|
|
26497
|
+
signal?.throwIfAborted();
|
|
25394
26498
|
agent.followup(message);
|
|
26499
|
+
abortPrompt = () => {
|
|
26500
|
+
livePrompt = void 0;
|
|
26501
|
+
if (typeof agent.cancel === "function")
|
|
26502
|
+
agent.cancel({ kind: "user" });
|
|
26503
|
+
else if (requestedExecutionId !== void 0)
|
|
26504
|
+
void releaseExecutionHandle();
|
|
26505
|
+
else
|
|
26506
|
+
void releaseHandle();
|
|
26507
|
+
};
|
|
26508
|
+
signal?.addEventListener("abort", abortPrompt, { once: true });
|
|
26509
|
+
if (signal?.aborted)
|
|
26510
|
+
abortPrompt();
|
|
25395
26511
|
await agent.whenIdle();
|
|
26512
|
+
signal?.throwIfAborted();
|
|
25396
26513
|
throwIfDisposed(disposed, lifecycleAbort.signal, "prompt");
|
|
25397
26514
|
await sessions.flush(agent.session);
|
|
25398
26515
|
throwIfDisposed(disposed, lifecycleAbort.signal, "prompt");
|
|
@@ -25403,11 +26520,14 @@ ${JSON.stringify(historyContext.items)}`;
|
|
|
25403
26520
|
events: snapshotFrom(fromSequence, requestedExecutionId)
|
|
25404
26521
|
};
|
|
25405
26522
|
} finally {
|
|
26523
|
+
if (abortPrompt)
|
|
26524
|
+
signal?.removeEventListener("abort", abortPrompt);
|
|
25406
26525
|
if (selectionRef !== void 0) {
|
|
25407
26526
|
selectionRef.current = void 0;
|
|
25408
26527
|
selectionRef.assembled = void 0;
|
|
25409
26528
|
}
|
|
25410
26529
|
disposeSelection?.();
|
|
26530
|
+
livePrompt = void 0;
|
|
25411
26531
|
promptActive = false;
|
|
25412
26532
|
}
|
|
25413
26533
|
};
|
|
@@ -25471,7 +26591,7 @@ ${JSON.stringify(historyContext.items)}`;
|
|
|
25471
26591
|
} catch {
|
|
25472
26592
|
}
|
|
25473
26593
|
try {
|
|
25474
|
-
await
|
|
26594
|
+
await contextOperationPromise;
|
|
25475
26595
|
} catch {
|
|
25476
26596
|
}
|
|
25477
26597
|
try {
|
|
@@ -25486,20 +26606,33 @@ ${JSON.stringify(historyContext.items)}`;
|
|
|
25486
26606
|
return disposePromise;
|
|
25487
26607
|
};
|
|
25488
26608
|
return {
|
|
25489
|
-
sessionId
|
|
26609
|
+
get sessionId() {
|
|
26610
|
+
return nativeSessionId;
|
|
26611
|
+
},
|
|
26612
|
+
...options.contextBinding === void 0 ? {} : { contextDeletionVersion: 1 },
|
|
26613
|
+
resetCanonicalContext(revision) {
|
|
26614
|
+
if (contextOperationPromise !== void 0)
|
|
26615
|
+
return Promise.reject(new Error("DSH host facade permits only one active context operation"));
|
|
26616
|
+
const operation = resetCanonicalContext(revision);
|
|
26617
|
+
contextOperationPromise = operation;
|
|
26618
|
+
return operation.finally(() => {
|
|
26619
|
+
if (contextOperationPromise === operation)
|
|
26620
|
+
contextOperationPromise = void 0;
|
|
26621
|
+
});
|
|
26622
|
+
},
|
|
25490
26623
|
open: open7,
|
|
25491
26624
|
currentSequence(requestedExecutionId) {
|
|
25492
26625
|
return operationAgent(requestedExecutionId).session.seq;
|
|
25493
26626
|
},
|
|
25494
26627
|
snapshotFrom,
|
|
25495
26628
|
prepareContextExecution(input2) {
|
|
25496
|
-
if (
|
|
26629
|
+
if (contextOperationPromise !== void 0)
|
|
25497
26630
|
return Promise.reject(new Error("DSH host facade permits only one active context preparation"));
|
|
25498
26631
|
const operation = prepareContextExecution(input2);
|
|
25499
|
-
|
|
26632
|
+
contextOperationPromise = operation;
|
|
25500
26633
|
return operation.finally(() => {
|
|
25501
|
-
if (
|
|
25502
|
-
|
|
26634
|
+
if (contextOperationPromise === operation)
|
|
26635
|
+
contextOperationPromise = void 0;
|
|
25503
26636
|
});
|
|
25504
26637
|
},
|
|
25505
26638
|
projectCanonicalEvents,
|
|
@@ -25511,6 +26644,12 @@ ${JSON.stringify(historyContext.items)}`;
|
|
|
25511
26644
|
eventSubscribers.add(listener);
|
|
25512
26645
|
return () => eventSubscribers.delete(listener);
|
|
25513
26646
|
},
|
|
26647
|
+
onLiveOutput(listener) {
|
|
26648
|
+
if (disposed)
|
|
26649
|
+
throw new Error("DSH host facade is disposed");
|
|
26650
|
+
liveSubscribers.add(listener);
|
|
26651
|
+
return () => liveSubscribers.delete(listener);
|
|
26652
|
+
},
|
|
25514
26653
|
onStatus(listener) {
|
|
25515
26654
|
if (disposed)
|
|
25516
26655
|
throw new Error("DSH host facade is disposed");
|
|
@@ -25543,6 +26682,7 @@ async function registerDshNativeWorkspace(contextValue, workspacePath, workspace
|
|
|
25543
26682
|
const sessionQuery = requireService(context, "sessionQuery", ["readSession"]);
|
|
25544
26683
|
const sessionTitle = requireService(context, "sessionTitle", ["rename", "get"]);
|
|
25545
26684
|
const completed = /* @__PURE__ */ new Map();
|
|
26685
|
+
const retired = /* @__PURE__ */ new Set();
|
|
25546
26686
|
const observedSessionIds = new Set(workspace.sessionIds);
|
|
25547
26687
|
const runningSessionIds = /* @__PURE__ */ new Set();
|
|
25548
26688
|
const offActivity = context.on("agent/status", (...args) => {
|
|
@@ -25563,6 +26703,10 @@ async function registerDshNativeWorkspace(contextValue, workspacePath, workspace
|
|
|
25563
26703
|
return;
|
|
25564
26704
|
observedSessionIds.add(session.id);
|
|
25565
26705
|
const event = asSessionEvent(args[1]);
|
|
26706
|
+
if (event?.type === "user/message" && /^gatherthread-retired:[0-9]+$/.test(String(asObject4(event.data)?.id)) && asObject4(asObject4(event.data)?.source)?.plugin === "gatherthread") {
|
|
26707
|
+
retired.add(session.id);
|
|
26708
|
+
completed.delete(session.id);
|
|
26709
|
+
}
|
|
25566
26710
|
if (event?.type === "turn/start")
|
|
25567
26711
|
runningSessionIds.add(session.id);
|
|
25568
26712
|
if (event?.type === "turn/end")
|
|
@@ -25613,6 +26757,10 @@ async function registerDshNativeWorkspace(contextValue, workspacePath, workspace
|
|
|
25613
26757
|
for (const localSessionId of [...currentIds]) {
|
|
25614
26758
|
if (!isUserCreatedDshSessionId(localSessionId))
|
|
25615
26759
|
continue;
|
|
26760
|
+
if (retired.has(localSessionId)) {
|
|
26761
|
+
candidates.delete(localSessionId);
|
|
26762
|
+
continue;
|
|
26763
|
+
}
|
|
25616
26764
|
const cached2 = completed.get(localSessionId);
|
|
25617
26765
|
if (cached2 !== void 0)
|
|
25618
26766
|
continue;
|
|
@@ -25627,8 +26775,11 @@ async function registerDshNativeWorkspace(contextValue, workspacePath, workspace
|
|
|
25627
26775
|
throw new Error("Pinned DSH Session reader returned an invalid event");
|
|
25628
26776
|
return parsed;
|
|
25629
26777
|
});
|
|
25630
|
-
if (!hasCompletedDshLocalTurn(events, localSessionId))
|
|
26778
|
+
if (!hasCompletedDshLocalTurn(events, localSessionId)) {
|
|
26779
|
+
completed.delete(localSessionId);
|
|
26780
|
+
candidates.delete(localSessionId);
|
|
25631
26781
|
continue;
|
|
26782
|
+
}
|
|
25632
26783
|
const title = live === void 0 ? titleFromEvents(events) : normalizedLocalSessionTitle(sessionTitle.get(live)?.title) ?? titleFromEvents(events);
|
|
25633
26784
|
const candidate = { localSessionId, title };
|
|
25634
26785
|
completed.set(localSessionId, candidate);
|
|
@@ -25653,8 +26804,10 @@ async function registerDshNativeWorkspace(contextValue, workspacePath, workspace
|
|
|
25653
26804
|
return;
|
|
25654
26805
|
events.push(parsed);
|
|
25655
26806
|
}
|
|
25656
|
-
if (!hasCompletedDshLocalTurn(events, session.id))
|
|
26807
|
+
if (!hasCompletedDshLocalTurn(events, session.id)) {
|
|
26808
|
+
completed.delete(session.id);
|
|
25657
26809
|
return;
|
|
26810
|
+
}
|
|
25658
26811
|
completed.set(session.id, {
|
|
25659
26812
|
localSessionId: session.id,
|
|
25660
26813
|
title: normalizedLocalSessionTitle(sessionTitle.get(session)?.title) ?? titleFromEvents(events)
|
|
@@ -26784,7 +27937,7 @@ function publicError2(error62, fallback) {
|
|
|
26784
27937
|
}
|
|
26785
27938
|
|
|
26786
27939
|
// dist/src/state-store.js
|
|
26787
|
-
import { randomUUID as
|
|
27940
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
26788
27941
|
import { constants as constants4 } from "node:fs";
|
|
26789
27942
|
import { lstat as lstat7, mkdir as mkdir5, open as open6, rename as rename3, unlink as unlink4 } from "node:fs/promises";
|
|
26790
27943
|
import path9 from "node:path";
|
|
@@ -26839,7 +27992,7 @@ var FileConnectorStateStore = class {
|
|
|
26839
27992
|
const targetBefore = await optionalLstat(this.#path);
|
|
26840
27993
|
if (targetBefore !== void 0)
|
|
26841
27994
|
assertPrivateRegularFile(targetBefore, "DSH connector state");
|
|
26842
|
-
const temporaryPath = `${this.#path}.tmp-${process.pid}-${
|
|
27995
|
+
const temporaryPath = `${this.#path}.tmp-${process.pid}-${randomUUID6()}`;
|
|
26843
27996
|
const handle = await open6(temporaryPath, "wx", 384);
|
|
26844
27997
|
try {
|
|
26845
27998
|
await handle.writeFile(`${JSON.stringify(validated, null, 2)}
|
|
@@ -26879,7 +28032,10 @@ function validateConnectorState(value) {
|
|
|
26879
28032
|
"publishedDshSequence",
|
|
26880
28033
|
...legacyUploadPolicy ? [] : ["automaticUpload"],
|
|
26881
28034
|
"activeRequest",
|
|
26882
|
-
"outbox"
|
|
28035
|
+
"outbox",
|
|
28036
|
+
"contentRevision",
|
|
28037
|
+
"projectionSessionId",
|
|
28038
|
+
"localOnlySessionIds"
|
|
26883
28039
|
]), "state");
|
|
26884
28040
|
if (state.version !== 1 && state.version !== 2 && state.version !== 3) {
|
|
26885
28041
|
throw new Error("Unsupported DSH connector state version");
|
|
@@ -26894,6 +28050,9 @@ function validateConnectorState(value) {
|
|
|
26894
28050
|
throw new Error("state.outbox must be an array");
|
|
26895
28051
|
const outbox = state.outbox.map(parseOutboxOperation);
|
|
26896
28052
|
const validated = {
|
|
28053
|
+
...state.contentRevision === void 0 ? {} : { contentRevision: nonNegativeInteger(state.contentRevision, "state.contentRevision") },
|
|
28054
|
+
...state.projectionSessionId === void 0 ? {} : { projectionSessionId: safeString(state.projectionSessionId, "state.projectionSessionId", 128) },
|
|
28055
|
+
...state.localOnlySessionIds === void 0 ? {} : { localOnlySessionIds: parseRetiredSessionIds(state.localOnlySessionIds) },
|
|
26897
28056
|
version: 3,
|
|
26898
28057
|
binding: {
|
|
26899
28058
|
projectId: safeString(binding.projectId, "state.binding.projectId", 128),
|
|
@@ -26912,8 +28071,9 @@ function validateConnectorState(value) {
|
|
|
26912
28071
|
}
|
|
26913
28072
|
function parseActiveRequest(value) {
|
|
26914
28073
|
const active = requiredObject4(value, "state.activeRequest");
|
|
26915
|
-
exactKeys(active, /* @__PURE__ */ new Set(["requestId", "requestSequence", "dshFromSequence", "dshToSequence", "promptDigest", "claimAttempt", "contextExecution"]), "state.activeRequest");
|
|
28074
|
+
exactKeys(active, /* @__PURE__ */ new Set(["requestId", "requestSequence", "dshFromSequence", "dshToSequence", "promptDigest", "claimAttempt", "contextExecution", "contentRevision"]), "state.activeRequest");
|
|
26916
28075
|
const parsed = {
|
|
28076
|
+
...active.contentRevision === void 0 ? {} : { contentRevision: nonNegativeInteger(active.contentRevision, "state.activeRequest.contentRevision") },
|
|
26917
28077
|
requestId: safeString(active.requestId, "state.activeRequest.requestId", 128),
|
|
26918
28078
|
requestSequence: positiveInteger(active.requestSequence, "state.activeRequest.requestSequence"),
|
|
26919
28079
|
dshFromSequence: nonNegativeInteger(active.dshFromSequence, "state.activeRequest.dshFromSequence"),
|
|
@@ -26989,7 +28149,8 @@ function parseLocalTurnInput(value, label) {
|
|
|
26989
28149
|
"observedReasoningEffort",
|
|
26990
28150
|
"requestPayload",
|
|
26991
28151
|
"responsePayload",
|
|
26992
|
-
"toolEvents"
|
|
28152
|
+
"toolEvents",
|
|
28153
|
+
"contentRevision"
|
|
26993
28154
|
]), label);
|
|
26994
28155
|
const occurredAt = safeString(input2.occurredAt, `${label}.occurredAt`, 64);
|
|
26995
28156
|
if (!Number.isFinite(Date.parse(occurredAt)))
|
|
@@ -26999,6 +28160,7 @@ function parseLocalTurnInput(value, label) {
|
|
|
26999
28160
|
}
|
|
27000
28161
|
return {
|
|
27001
28162
|
localTurnId: safeString(input2.localTurnId, `${label}.localTurnId`, 200),
|
|
28163
|
+
...input2.contentRevision === void 0 ? {} : { contentRevision: nonNegativeInteger(input2.contentRevision, `${label}.contentRevision`) },
|
|
27002
28164
|
runtimeId: safeString(input2.runtimeId, `${label}.runtimeId`, 128),
|
|
27003
28165
|
basedOnSequence: nonNegativeInteger(input2.basedOnSequence, `${label}.basedOnSequence`),
|
|
27004
28166
|
occurredAt,
|
|
@@ -27026,13 +28188,15 @@ function parseAppendInput(value, label) {
|
|
|
27026
28188
|
"runtimeId",
|
|
27027
28189
|
"claimAttempt",
|
|
27028
28190
|
"observedModel",
|
|
27029
|
-
"observedReasoningEffort"
|
|
28191
|
+
"observedReasoningEffort",
|
|
28192
|
+
"contentRevision"
|
|
27030
28193
|
]), label);
|
|
27031
28194
|
if (input2.type !== "tool_call" && input2.type !== "tool_result") {
|
|
27032
28195
|
throw new Error(`${label}.type must be tool_call or tool_result`);
|
|
27033
28196
|
}
|
|
27034
28197
|
return {
|
|
27035
28198
|
type: input2.type,
|
|
28199
|
+
...input2.contentRevision === void 0 ? {} : { contentRevision: nonNegativeInteger(input2.contentRevision, `${label}.contentRevision`) },
|
|
27036
28200
|
idempotencyKey: safeString(input2.idempotencyKey, `${label}.idempotencyKey`, 200),
|
|
27037
28201
|
payload: jsonValue(input2.payload, `${label}.payload`),
|
|
27038
28202
|
...input2.replyTo === void 0 ? {} : { replyTo: safeString(input2.replyTo, `${label}.replyTo`, 128) },
|
|
@@ -27049,9 +28213,10 @@ function parseAppendInput(value, label) {
|
|
|
27049
28213
|
}
|
|
27050
28214
|
function parseCompletionInput(value, label) {
|
|
27051
28215
|
const input2 = requiredObject4(value, label);
|
|
27052
|
-
exactKeys(input2, /* @__PURE__ */ new Set(["runtimeId", "claimAttempt", "idempotencyKey", "payload", "observedModel", "observedReasoningEffort"]), label);
|
|
28216
|
+
exactKeys(input2, /* @__PURE__ */ new Set(["runtimeId", "claimAttempt", "idempotencyKey", "payload", "observedModel", "observedReasoningEffort", "contentRevision"]), label);
|
|
27053
28217
|
return {
|
|
27054
28218
|
runtimeId: safeString(input2.runtimeId, `${label}.runtimeId`, 128),
|
|
28219
|
+
...input2.contentRevision === void 0 ? {} : { contentRevision: nonNegativeInteger(input2.contentRevision, `${label}.contentRevision`) },
|
|
27055
28220
|
...input2.claimAttempt === void 0 ? {} : {
|
|
27056
28221
|
claimAttempt: positiveInteger(input2.claimAttempt, `${label}.claimAttempt`)
|
|
27057
28222
|
},
|
|
@@ -27063,6 +28228,11 @@ function parseCompletionInput(value, label) {
|
|
|
27063
28228
|
}
|
|
27064
28229
|
};
|
|
27065
28230
|
}
|
|
28231
|
+
function parseRetiredSessionIds(value) {
|
|
28232
|
+
if (!Array.isArray(value) || value.length > 4096 || new Set(value).size !== value.length)
|
|
28233
|
+
throw new Error("Invalid DSH retired Session identities");
|
|
28234
|
+
return value.map((id, index) => safeString(id, `state.localOnlySessionIds[${index}]`, 128));
|
|
28235
|
+
}
|
|
27066
28236
|
function assertAlreadyRedacted(state) {
|
|
27067
28237
|
const encoded = JSON.stringify(state);
|
|
27068
28238
|
const redacted = JSON.stringify(redactValue(state));
|
|
@@ -27889,9 +29059,13 @@ var DshNativeHostController = class {
|
|
|
27889
29059
|
if (route === void 0)
|
|
27890
29060
|
return;
|
|
27891
29061
|
throwIfAborted(signal);
|
|
27892
|
-
const
|
|
29062
|
+
const catalogUpdate = await this.#refreshExecutionProfiles(route, signal);
|
|
27893
29063
|
throwIfAborted(signal);
|
|
27894
|
-
if (
|
|
29064
|
+
if (catalogUpdate === "route_unavailable") {
|
|
29065
|
+
await this.#abandonUnavailableRoute(grant);
|
|
29066
|
+
return;
|
|
29067
|
+
}
|
|
29068
|
+
if (catalogUpdate === "changed") {
|
|
27895
29069
|
for (const owner of this.#owners.values())
|
|
27896
29070
|
this.#pendingProfileOwners.add(owner);
|
|
27897
29071
|
}
|
|
@@ -27933,16 +29107,17 @@ var DshNativeHostController = class {
|
|
|
27933
29107
|
/**
|
|
27934
29108
|
* Re-read the harness catalog when the route changed or the entry went stale.
|
|
27935
29109
|
*
|
|
27936
|
-
* Returns whether the catalog differs from the one already advertised
|
|
27937
|
-
*
|
|
27938
|
-
*
|
|
27939
|
-
*
|
|
29110
|
+
* Returns whether the catalog differs from the one already advertised, or that
|
|
29111
|
+
* DSH no longer offers the model this connection runs. Discovery is cached per
|
|
29112
|
+
* route and also time-bounded: DSH publishes a model metadata catalog that can
|
|
29113
|
+
* gain models while a connection stays open, so a connect-time snapshot would
|
|
29114
|
+
* otherwise keep offering the old list for the life of the process.
|
|
27940
29115
|
*/
|
|
27941
29116
|
async #refreshExecutionProfiles(route, signal) {
|
|
27942
29117
|
const routeKey = `${route.provider}\0${route.model}`;
|
|
27943
29118
|
const discoveredAt = this.#executionProfilesDiscoveredAt;
|
|
27944
29119
|
if (this.#executionProfileRouteKey === routeKey && discoveredAt !== void 0 && this.#now() - discoveredAt < EXECUTION_PROFILE_REFRESH_INTERVAL_MS) {
|
|
27945
|
-
return
|
|
29120
|
+
return "unchanged";
|
|
27946
29121
|
}
|
|
27947
29122
|
const previous = this.#executionProfiles;
|
|
27948
29123
|
const remember = (profiles2) => {
|
|
@@ -27950,18 +29125,44 @@ var DshNativeHostController = class {
|
|
|
27950
29125
|
this.#executionProfiles = profiles2;
|
|
27951
29126
|
this.#executionProfileRouteKey = routeKey;
|
|
27952
29127
|
this.#executionProfilesDiscoveredAt = this.#now();
|
|
27953
|
-
return changed;
|
|
29128
|
+
return changed ? "changed" : "unchanged";
|
|
27954
29129
|
};
|
|
27955
29130
|
if (route.provider !== "deepseek-official")
|
|
27956
29131
|
return remember(void 0);
|
|
27957
29132
|
const discovered = this.#options.listExecutionProfiles === void 0 ? await listNativeExecutionProfiles(this.#options.context, route.provider, signal) : await this.#options.listExecutionProfiles(route.provider, signal);
|
|
27958
29133
|
throwIfAborted(signal);
|
|
27959
29134
|
const profiles = normalizeExecutionProfiles(discovered, route.provider);
|
|
27960
|
-
if (!profiles.some((profile) => profile.model === route.model))
|
|
27961
|
-
|
|
27962
|
-
}
|
|
29135
|
+
if (!profiles.some((profile) => profile.model === route.model))
|
|
29136
|
+
return "route_unavailable";
|
|
27963
29137
|
return remember(profiles);
|
|
27964
29138
|
}
|
|
29139
|
+
/**
|
|
29140
|
+
* Drop the route after DSH stops offering the model this connection runs.
|
|
29141
|
+
*
|
|
29142
|
+
* A harness catalog is the authority on what a runtime can run, so the route is
|
|
29143
|
+
* abandoned instead of being repointed at another model: registering a
|
|
29144
|
+
* replacement silently would run a model this device never selected. Clearing the
|
|
29145
|
+
* stored route returns the connection to the state it has before its first
|
|
29146
|
+
* selection, where the panel asks for an explicit provider and model against the
|
|
29147
|
+
* harness's current catalog. Owners and the cached declaration go with it, so
|
|
29148
|
+
* nothing keeps advertising the profiles and bindings built from the dropped route.
|
|
29149
|
+
*/
|
|
29150
|
+
async #abandonUnavailableRoute(grant) {
|
|
29151
|
+
await this.#stopOwners();
|
|
29152
|
+
this.#executionProfiles = void 0;
|
|
29153
|
+
this.#executionProfileRouteKey = void 0;
|
|
29154
|
+
this.#executionProfilesDiscoveredAt = void 0;
|
|
29155
|
+
this.#grant = await this.#credentials.save({
|
|
29156
|
+
schemaVersion: grant.schemaVersion,
|
|
29157
|
+
serverUrl: grant.serverUrl,
|
|
29158
|
+
apiUrl: grant.apiUrl,
|
|
29159
|
+
deviceId: grant.deviceId,
|
|
29160
|
+
deviceName: grant.deviceName,
|
|
29161
|
+
token: grant.token
|
|
29162
|
+
});
|
|
29163
|
+
this.#recoverableError = "route_unavailable";
|
|
29164
|
+
this.#options.status.setConnection("stopped");
|
|
29165
|
+
}
|
|
27965
29166
|
/**
|
|
27966
29167
|
* Republish the current catalog to every owner that has not confirmed it.
|
|
27967
29168
|
*
|