@p4code/cli 0.1.15 → 0.1.17
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 +1 -1
- package/dist/bin.mjs +1791 -252
- package/dist/client/assets/{DiffPanel-Btlwh6tZ.js → DiffPanel-BrM3QqVj.js} +3 -3
- package/dist/client/assets/{FilePreviewPanel-CJRGrUq9.js → FilePreviewPanel-DXk_4dj4.js} +5 -5
- package/dist/client/assets/PreviewPanel-DfngnmUt.js +2 -0
- package/dist/client/assets/{angular-html-BjmAeE7T.js → angular-html-veA1EpVJ.js} +2 -2
- package/dist/client/assets/{angular-ts-BBpxlOlP.js → angular-ts-CjhObYqk.js} +2 -2
- package/dist/client/assets/{apl-BbgMrCuX.js → apl-BaBqmioI.js} +2 -2
- package/dist/client/assets/arrow-right-Cvlj0Cvu.js +2 -0
- package/dist/client/assets/{astro-mUvWYN-n.js → astro-aZep3bUH.js} +2 -2
- package/dist/client/assets/{blade-B5QWyKCP.js → blade-B-PS40R8.js} +2 -2
- package/dist/client/assets/{c-BfHpmPOy.js → c-Da6G9SJL.js} +2 -2
- package/dist/client/assets/{cobol-DLZOS_vG.js → cobol-MFD_Q4Xa.js} +2 -2
- package/dist/client/assets/{coffee-9TkBNWbZ.js → coffee-DOKaGG2H.js} +2 -2
- package/dist/client/assets/{cpp-qjIc-2IN.js → cpp-iD8OoA0X.js} +2 -2
- package/dist/client/assets/{crystal-DCOpXRVe.js → crystal-BgCh46iL.js} +2 -2
- package/dist/client/assets/{css-Xrxx3evf.js → css-C0AvK1Fp.js} +2 -2
- package/dist/client/assets/{edge-BJXKMMao.js → edge-DWC_9CO2.js} +2 -2
- package/dist/client/assets/{elixir-_uRFN4Aw.js → elixir-5ahlHJpU.js} +2 -2
- package/dist/client/assets/{elm-fwfp6NdI.js → elm-B4b4KSk0.js} +2 -2
- package/dist/client/assets/{erb-DfSw8n3G.js → erb-CNRZFKcV.js} +2 -2
- package/dist/client/assets/{fileCommentAnnotations-BCnpdEVp.js → fileCommentAnnotations-V3SOLaB4.js} +2 -2
- package/dist/client/assets/{git-rebase-CwGd8ZXk.js → git-rebase-AbfQBerd.js} +2 -2
- package/dist/client/assets/{glimmer-js-DIl7yS9j.js → glimmer-js-_dx97vsR.js} +2 -2
- package/dist/client/assets/{glimmer-ts-ClbRblrS.js → glimmer-ts-BFmDDwi5.js} +2 -2
- package/dist/client/assets/{glsl-DPbTpA_H.js → glsl-CXroyNbj.js} +2 -2
- package/dist/client/assets/{graphql-Ugw-cmPb.js → graphql-RU5TF49j.js} +2 -2
- package/dist/client/assets/{hack-BNaGlFKY.js → hack-S6OyQkI3.js} +2 -2
- package/dist/client/assets/{haml-CADPiQL8.js → haml-CclbQxsV.js} +2 -2
- package/dist/client/assets/{handlebars-lMMkQPVI.js → handlebars-DFD506ku.js} +2 -2
- package/dist/client/assets/{html-dV4yJf1E.js → html-BtV0fnqE.js} +2 -2
- package/dist/client/assets/{html-derivative-DC417Zuq.js → html-derivative-oHJ5ggVN.js} +2 -2
- package/dist/client/assets/{http-DHNl1S4G.js → http-C8JeRqCn.js} +2 -2
- package/dist/client/assets/{hurl-MeTzE8YN.js → hurl-C1cew6hc.js} +2 -2
- package/dist/client/assets/index-5pO5drbg.js +768 -0
- package/dist/client/assets/index-Dol3ssFp.css +1 -0
- package/dist/client/assets/{java-_z6VtRIC.js → java-CrUEPeR7.js} +2 -2
- package/dist/client/assets/{javascript-mzH0UoeT.js → javascript-DJT7psEs.js} +2 -2
- package/dist/client/assets/{jinja-CcSfwgQN.js → jinja-CXxzh_AI.js} +2 -2
- package/dist/client/assets/{jison-Dnr6DQYK.js → jison-BEgWlYuP.js} +2 -2
- package/dist/client/assets/{json-xiKHc2eN.js → json-DYMLm7oI.js} +2 -2
- package/dist/client/assets/{jsx-B0uBKQ5P.js → jsx-C2i-6RBR.js} +2 -2
- package/dist/client/assets/{julia-Du1DH_tJ.js → julia-268B5DSC.js} +2 -2
- package/dist/client/assets/{just-DlyxJRKQ.js → just-DHlfSR_g.js} +2 -2
- package/dist/client/assets/{latex-FzyaW41z.js → latex-hZJ97DlU.js} +2 -2
- package/dist/client/assets/{liquid-n6xLDAue.js → liquid-BXWKgP9a.js} +2 -2
- package/dist/client/assets/{lua-DL20UMyO.js → lua-DZpMPVk1.js} +2 -2
- package/dist/client/assets/{marko-OhxSvhVO.js → marko-C4krJn5M.js} +2 -2
- package/dist/client/assets/{mdc-JFr_O-f6.js → mdc-DPMybKM9.js} +2 -2
- package/dist/client/assets/{nginx-DO3MRFFZ.js → nginx-DS7EZxTP.js} +2 -2
- package/dist/client/assets/{nim-gxiT3Pjh.js → nim-DQ5EIgDG.js} +2 -2
- package/dist/client/assets/{perl-uO1ltvnm.js → perl-BYRfkLcm.js} +2 -2
- package/dist/client/assets/{php-DkSF6XhT.js → php-CRmJir-2.js} +2 -2
- package/dist/client/assets/{pug-D6ks186t.js → pug-ChlH277L.js} +2 -2
- package/dist/client/assets/{qml-CsabseTB.js → qml-D03lc83e.js} +2 -2
- package/dist/client/assets/{r-UjYqKhF6.js → r-B0iWOCwM.js} +2 -2
- package/dist/client/assets/{razor-Dr34iB-_.js → razor-jqTSj5Nf.js} +2 -2
- package/dist/client/assets/{regexp-BG9MLSbj.js → regexp-BtdW0BtX.js} +2 -2
- package/dist/client/assets/{rst-I9GYrav4.js → rst-ODlKAfCn.js} +2 -2
- package/dist/client/assets/{ruby-DQZcmBTL.js → ruby-D3-MIdGC.js} +2 -2
- package/dist/client/assets/{sas-To8Ja79N.js → sas-CHM8NNaC.js} +2 -2
- package/dist/client/assets/{scss-KhIYRETT.js → scss-C5u0ylVF.js} +2 -2
- package/dist/client/assets/{shellscript-B3M9HD4S.js → shellscript-e38vxsyD.js} +2 -2
- package/dist/client/assets/{shellsession-DCI3i_rX.js → shellsession-C2xN505I.js} +2 -2
- package/dist/client/assets/{soy-11gkdBZx.js → soy-Cm15Zvq3.js} +2 -2
- package/dist/client/assets/{sql-Dc2GulG4.js → sql-BpFtjTfW.js} +2 -2
- package/dist/client/assets/{stata-Br5SUE30.js → stata-BlPPmFYy.js} +2 -2
- package/dist/client/assets/{surrealql-Rg04dQNn.js → surrealql-BCULE51k.js} +2 -2
- package/dist/client/assets/{svelte-CtlB9-BL.js → svelte-BNRSv2pn.js} +2 -2
- package/dist/client/assets/{templ-Du0y714B.js → templ-DoGq1v8F.js} +2 -2
- package/dist/client/assets/{tex-DujbYFg6.js → tex--cpmM4NW.js} +2 -2
- package/dist/client/assets/textarea-M0r5voiR.js +46 -0
- package/dist/client/assets/{ts-tags-D1giNT28.js → ts-tags-D5eCylEK.js} +2 -2
- package/dist/client/assets/{tsx-6OJBHQve.js → tsx-Bu8K9CNP.js} +2 -2
- package/dist/client/assets/{twig-CsGDI-1m.js → twig-BZHf1w2v.js} +2 -2
- package/dist/client/assets/{typescript-BK1jdq6h.js → typescript-CdzN72UO.js} +2 -2
- package/dist/client/assets/{vue-CcdGezrU.js → vue-BZJs2XXT.js} +2 -2
- package/dist/client/assets/{vue-html-Cki3bF1b.js → vue-html-zt0y5fO9.js} +2 -2
- package/dist/client/assets/{vue-vine-CqNi4Hn_.js → vue-vine-SsQX7Kll.js} +2 -2
- package/dist/client/assets/{xml-By8mAu2E.js → xml-BKlTVdhA.js} +2 -2
- package/dist/client/assets/{xsl-DWgCtTr-.js → xsl-B00O3UQ-.js} +2 -2
- package/dist/client/assets/{yaml-DZTshk4U.js → yaml-Dr4fa503.js} +2 -2
- package/dist/client/index.html +3 -3
- package/package.json +1 -1
- package/dist/client/assets/PreviewPanel-CM8chpxZ.js +0 -2
- package/dist/client/assets/arrow-right-DYd55OqT.js +0 -2
- package/dist/client/assets/index-BmkbvCRH.js +0 -660
- package/dist/client/assets/index-DvMVFBig.css +0 -1
- package/dist/client/assets/textarea-C3IX8FEW.js +0 -46
package/dist/bin.mjs
CHANGED
|
@@ -233,7 +233,7 @@ const make$75 = () => {
|
|
|
233
233
|
const layer$71 = Layer.sync(NetService, make$75);
|
|
234
234
|
//#endregion
|
|
235
235
|
//#region package.json
|
|
236
|
-
var version = "0.1.
|
|
236
|
+
var version = "0.1.17";
|
|
237
237
|
//#endregion
|
|
238
238
|
//#region src/config.ts
|
|
239
239
|
/**
|
|
@@ -1509,6 +1509,7 @@ const CODEX_DRIVER_KIND = ProviderDriverKind.make("codex");
|
|
|
1509
1509
|
const CLAUDE_DRIVER_KIND = ProviderDriverKind.make("claudeAgent");
|
|
1510
1510
|
const CURSOR_DRIVER_KIND = ProviderDriverKind.make("cursor");
|
|
1511
1511
|
const GROK_DRIVER_KIND$1 = ProviderDriverKind.make("grok");
|
|
1512
|
+
const MUSE_DRIVER_KIND = ProviderDriverKind.make("muse");
|
|
1512
1513
|
const OPENCODE_DRIVER_KIND = ProviderDriverKind.make("opencode");
|
|
1513
1514
|
const DEFAULT_MODEL = "gpt-5.6-sol";
|
|
1514
1515
|
/**
|
|
@@ -1523,6 +1524,7 @@ const DEFAULT_MODEL_BY_PROVIDER = {
|
|
|
1523
1524
|
[CLAUDE_DRIVER_KIND]: "claude-sonnet-5",
|
|
1524
1525
|
[CURSOR_DRIVER_KIND]: "auto",
|
|
1525
1526
|
[GROK_DRIVER_KIND$1]: "grok-build",
|
|
1527
|
+
[MUSE_DRIVER_KIND]: "muse-spark-1.2",
|
|
1526
1528
|
[OPENCODE_DRIVER_KIND]: "openai/gpt-5"
|
|
1527
1529
|
};
|
|
1528
1530
|
/** Per-provider text generation model defaults. */
|
|
@@ -1530,6 +1532,7 @@ const DEFAULT_TEXT_GENERATION_MODEL_BY_PROVIDER = {
|
|
|
1530
1532
|
[CODEX_DRIVER_KIND]: DEFAULT_TEXT_GENERATION_MODEL,
|
|
1531
1533
|
[CLAUDE_DRIVER_KIND]: "claude-haiku-4-5",
|
|
1532
1534
|
[CURSOR_DRIVER_KIND]: "composer-2",
|
|
1535
|
+
[MUSE_DRIVER_KIND]: "muse-spark-1.2-contributor",
|
|
1533
1536
|
[OPENCODE_DRIVER_KIND]: "openai/gpt-5"
|
|
1534
1537
|
};
|
|
1535
1538
|
const MODEL_SLUG_ALIASES_BY_PROVIDER = {
|
|
@@ -4618,6 +4621,7 @@ const RuntimeEventRawSource = Schema$1.Union([
|
|
|
4618
4621
|
Schema$1.Literal("claude.sdk.permission"),
|
|
4619
4622
|
Schema$1.Literal("codex.sdk.thread-event"),
|
|
4620
4623
|
Schema$1.Literal("opencode.sdk.event"),
|
|
4624
|
+
Schema$1.Literal("muse.exec.jsonl"),
|
|
4621
4625
|
Schema$1.Literal("acp.jsonrpc"),
|
|
4622
4626
|
Schema$1.TemplateLiteral([
|
|
4623
4627
|
"acp.",
|
|
@@ -5024,14 +5028,18 @@ const UserInputResolvedPayload = Schema$1.Struct({ answers: UnknownRecordSchema
|
|
|
5024
5028
|
const TaskStartedPayload = Schema$1.Struct({
|
|
5025
5029
|
taskId: RuntimeTaskId,
|
|
5026
5030
|
description: Schema$1.optional(TrimmedNonEmptyStringSchema$1),
|
|
5027
|
-
taskType: Schema$1.optional(TrimmedNonEmptyStringSchema$1)
|
|
5031
|
+
taskType: Schema$1.optional(TrimmedNonEmptyStringSchema$1),
|
|
5032
|
+
toolUseId: Schema$1.optional(TrimmedNonEmptyStringSchema$1),
|
|
5033
|
+
subagentType: Schema$1.optional(TrimmedNonEmptyStringSchema$1)
|
|
5028
5034
|
});
|
|
5029
5035
|
const TaskProgressPayload = Schema$1.Struct({
|
|
5030
5036
|
taskId: RuntimeTaskId,
|
|
5031
5037
|
description: TrimmedNonEmptyStringSchema$1,
|
|
5032
5038
|
summary: Schema$1.optional(TrimmedNonEmptyStringSchema$1),
|
|
5033
5039
|
usage: Schema$1.optional(Schema$1.Unknown),
|
|
5034
|
-
lastToolName: Schema$1.optional(TrimmedNonEmptyStringSchema$1)
|
|
5040
|
+
lastToolName: Schema$1.optional(TrimmedNonEmptyStringSchema$1),
|
|
5041
|
+
toolUseId: Schema$1.optional(TrimmedNonEmptyStringSchema$1),
|
|
5042
|
+
subagentType: Schema$1.optional(TrimmedNonEmptyStringSchema$1)
|
|
5035
5043
|
});
|
|
5036
5044
|
const TaskCompletedPayload = Schema$1.Struct({
|
|
5037
5045
|
taskId: RuntimeTaskId,
|
|
@@ -5041,7 +5049,8 @@ const TaskCompletedPayload = Schema$1.Struct({
|
|
|
5041
5049
|
"stopped"
|
|
5042
5050
|
]),
|
|
5043
5051
|
summary: Schema$1.optional(TrimmedNonEmptyStringSchema$1),
|
|
5044
|
-
usage: Schema$1.optional(Schema$1.Unknown)
|
|
5052
|
+
usage: Schema$1.optional(Schema$1.Unknown),
|
|
5053
|
+
toolUseId: Schema$1.optional(TrimmedNonEmptyStringSchema$1)
|
|
5045
5054
|
});
|
|
5046
5055
|
const HookStartedPayload = Schema$1.Struct({
|
|
5047
5056
|
hookId: TrimmedNonEmptyStringSchema$1,
|
|
@@ -5707,6 +5716,26 @@ const GrokSettings = makeProviderSettingsSchema({
|
|
|
5707
5716
|
})),
|
|
5708
5717
|
customModels: Schema$1.Array(Schema$1.String).pipe(Schema$1.withDecodingDefault(Effect.succeed([])), Schema$1.annotateKey({ providerSettingsForm: { hidden: true } }))
|
|
5709
5718
|
}, { order: ["binaryPath"] });
|
|
5719
|
+
const MuseSettings = makeProviderSettingsSchema({
|
|
5720
|
+
enabled: Schema$1.Boolean.pipe(Schema$1.withDecodingDefault(Effect.succeed(false)), Schema$1.annotateKey({ providerSettingsForm: { hidden: true } })),
|
|
5721
|
+
binaryPath: makeBinaryPathSetting("muse").pipe(Schema$1.annotateKey({
|
|
5722
|
+
title: "Binary path",
|
|
5723
|
+
description: "Path to the Muse Code binary.",
|
|
5724
|
+
providerSettingsForm: {
|
|
5725
|
+
placeholder: "muse",
|
|
5726
|
+
clearWhenEmpty: "omit"
|
|
5727
|
+
}
|
|
5728
|
+
})),
|
|
5729
|
+
baseUrl: TrimmedString.pipe(Schema$1.withDecodingDefault(Effect.succeed("")), Schema$1.annotateKey({
|
|
5730
|
+
title: "Base URL",
|
|
5731
|
+
description: "Override the Meta Model API base URL for this instance.",
|
|
5732
|
+
providerSettingsForm: {
|
|
5733
|
+
placeholder: "https://api.meta.ai/v1",
|
|
5734
|
+
clearWhenEmpty: "omit"
|
|
5735
|
+
}
|
|
5736
|
+
})),
|
|
5737
|
+
customModels: Schema$1.Array(Schema$1.String).pipe(Schema$1.withDecodingDefault(Effect.succeed([])), Schema$1.annotateKey({ providerSettingsForm: { hidden: true } }))
|
|
5738
|
+
}, { order: ["binaryPath", "baseUrl"] });
|
|
5710
5739
|
const OpenCodeSettings = makeProviderSettingsSchema({
|
|
5711
5740
|
enabled: Schema$1.Boolean.pipe(Schema$1.withDecodingDefault(Effect.succeed(true)), Schema$1.annotateKey({ providerSettingsForm: { hidden: true } })),
|
|
5712
5741
|
binaryPath: makeBinaryPathSetting("opencode").pipe(Schema$1.annotateKey({
|
|
@@ -5817,6 +5846,7 @@ const ServerSettings = Schema$1.Struct({
|
|
|
5817
5846
|
claudeAgent: ClaudeSettings.pipe(Schema$1.withDecodingDefault(Effect.succeed({}))),
|
|
5818
5847
|
cursor: CursorSettings.pipe(Schema$1.withDecodingDefault(Effect.succeed({}))),
|
|
5819
5848
|
grok: GrokSettings.pipe(Schema$1.withDecodingDefault(Effect.succeed({}))),
|
|
5849
|
+
muse: MuseSettings.pipe(Schema$1.withDecodingDefault(Effect.succeed({}))),
|
|
5820
5850
|
opencode: OpenCodeSettings.pipe(Schema$1.withDecodingDefault(Effect.succeed({})))
|
|
5821
5851
|
}).pipe(Schema$1.withDecodingDefault(Effect.succeed({}))),
|
|
5822
5852
|
providerInstances: Schema$1.Record(ProviderInstanceId, ProviderInstanceConfig).pipe(Schema$1.withDecodingDefault(Effect.succeed({}))),
|
|
@@ -5882,6 +5912,12 @@ const GrokSettingsPatch = Schema$1.Struct({
|
|
|
5882
5912
|
binaryPath: Schema$1.optionalKey(TrimmedString),
|
|
5883
5913
|
customModels: Schema$1.optionalKey(Schema$1.Array(Schema$1.String))
|
|
5884
5914
|
});
|
|
5915
|
+
const MuseSettingsPatch = Schema$1.Struct({
|
|
5916
|
+
enabled: Schema$1.optionalKey(Schema$1.Boolean),
|
|
5917
|
+
binaryPath: Schema$1.optionalKey(TrimmedString),
|
|
5918
|
+
baseUrl: Schema$1.optionalKey(TrimmedString),
|
|
5919
|
+
customModels: Schema$1.optionalKey(Schema$1.Array(Schema$1.String))
|
|
5920
|
+
});
|
|
5885
5921
|
const OpenCodeSettingsPatch = Schema$1.Struct({
|
|
5886
5922
|
enabled: Schema$1.optionalKey(Schema$1.Boolean),
|
|
5887
5923
|
binaryPath: Schema$1.optionalKey(TrimmedString),
|
|
@@ -5915,6 +5951,7 @@ const ServerSettingsPatch = Schema$1.Struct({
|
|
|
5915
5951
|
claudeAgent: Schema$1.optionalKey(ClaudeSettingsPatch),
|
|
5916
5952
|
cursor: Schema$1.optionalKey(CursorSettingsPatch),
|
|
5917
5953
|
grok: Schema$1.optionalKey(GrokSettingsPatch),
|
|
5954
|
+
muse: Schema$1.optionalKey(MuseSettingsPatch),
|
|
5918
5955
|
opencode: Schema$1.optionalKey(OpenCodeSettingsPatch)
|
|
5919
5956
|
})),
|
|
5920
5957
|
providerInstances: Schema$1.optionalKey(Schema$1.Record(ProviderInstanceId, ProviderInstanceConfig))
|
|
@@ -6054,6 +6091,14 @@ const ServerProvider = Schema$1.Struct({
|
|
|
6054
6091
|
continuation: Schema$1.optional(ServerProviderContinuation),
|
|
6055
6092
|
showInteractionModeToggle: Schema$1.optional(Schema$1.Boolean),
|
|
6056
6093
|
requiresNewThreadForModelChange: Schema$1.optional(Schema$1.Boolean),
|
|
6094
|
+
/**
|
|
6095
|
+
* Runtime modes this provider can actually honour. Absent means every
|
|
6096
|
+
* mode is available, which is the case for every provider that can ask
|
|
6097
|
+
* the user for an approval mid-turn. A provider that only runs headless
|
|
6098
|
+
* (Muse Code) lists the subset it can deliver, and clients disable the
|
|
6099
|
+
* rest instead of offering a mode the driver would silently downgrade.
|
|
6100
|
+
*/
|
|
6101
|
+
supportedRuntimeModes: Schema$1.optional(Schema$1.Array(RuntimeMode)),
|
|
6057
6102
|
enabled: Schema$1.Boolean,
|
|
6058
6103
|
installed: Schema$1.Boolean,
|
|
6059
6104
|
version: Schema$1.NullOr(TrimmedNonEmptyString),
|
|
@@ -7054,14 +7099,28 @@ const TASK_ASSIGNEE_MAX_LENGTH = 128;
|
|
|
7054
7099
|
* Board columns, in board order. `backlog` is the default for newly created
|
|
7055
7100
|
* tasks — an agent filing a task mid-session is recording work that exists, not
|
|
7056
7101
|
* committing to doing it next.
|
|
7102
|
+
*
|
|
7103
|
+
* `cancelled` is the other way a task closes: decided against, superseded or
|
|
7104
|
+
* merged into another task. Marking such a task `done` is the workaround it
|
|
7105
|
+
* replaces, and it lies - a board that says five things finished when two of
|
|
7106
|
+
* them were dropped is not worth reading.
|
|
7057
7107
|
*/
|
|
7058
7108
|
const TaskStatus = Schema$1.Literals([
|
|
7059
7109
|
"backlog",
|
|
7060
7110
|
"todo",
|
|
7061
7111
|
"in_progress",
|
|
7062
7112
|
"in_review",
|
|
7063
|
-
"done"
|
|
7113
|
+
"done",
|
|
7114
|
+
"cancelled"
|
|
7064
7115
|
]);
|
|
7116
|
+
/**
|
|
7117
|
+
* What a status this build has never heard of decodes to when read back.
|
|
7118
|
+
*
|
|
7119
|
+
* `backlog` is the least dishonest guess: it says "recorded, nothing claimed
|
|
7120
|
+
* about it", which is true of a status we cannot interpret. Guessing `done` or
|
|
7121
|
+
* `cancelled` would claim the task is closed.
|
|
7122
|
+
*/
|
|
7123
|
+
const UNKNOWN_TASK_STATUS_FALLBACK = "backlog";
|
|
7065
7124
|
const TaskPriority = Schema$1.Literals([
|
|
7066
7125
|
"none",
|
|
7067
7126
|
"low",
|
|
@@ -7093,7 +7152,19 @@ const ProjectIdField = ProjectId.pipe(Schema$1.annotateEncoded({ description: "I
|
|
|
7093
7152
|
const ThreadIdField = ThreadId.pipe(Schema$1.annotateEncoded({ description: "Id of the agent thread working this task." }));
|
|
7094
7153
|
const TitleField = TrimmedNonEmptyString.check(Schema$1.isMaxLength(TASK_TITLE_MAX_LENGTH)).pipe(Schema$1.annotateEncoded({ description: "One-line summary of the work. Required." }));
|
|
7095
7154
|
const BodyField = Schema$1.String.pipe(Schema$1.annotateEncoded({ description: "Markdown detail: context, acceptance criteria, links." }));
|
|
7096
|
-
const StatusField = TaskStatus.pipe(Schema$1.annotateEncoded({ description: "Board column: backlog (recorded, not queued), todo (queued next), in_progress, in_review, done." }));
|
|
7155
|
+
const StatusField = TaskStatus.pipe(Schema$1.annotateEncoded({ description: "Board column: backlog (recorded, not queued), todo (queued next), in_progress, in_review, done, cancelled (closed without doing the work)." }));
|
|
7156
|
+
/**
|
|
7157
|
+
* The status as read back from a store, tolerant of values this build predates.
|
|
7158
|
+
*
|
|
7159
|
+
* A board can be shared between machines running different versions, and a
|
|
7160
|
+
* newer peer may write a status added after this client shipped. A strict
|
|
7161
|
+
* literal would fail the decode of the whole page, so one unknown row would
|
|
7162
|
+
* blank the board behind a "hub is unavailable" error rather than degrade. An
|
|
7163
|
+
* unrecognized status therefore decodes to {@link UNKNOWN_TASK_STATUS_FALLBACK},
|
|
7164
|
+
* same spirit as the nullable `readableId` and `orderKey` below. Encoding stays
|
|
7165
|
+
* strict: this client can only ever write a status it knows.
|
|
7166
|
+
*/
|
|
7167
|
+
const StoredStatusField = TaskStatus.pipe(Schema$1.catchDecoding(() => Effect.succeedSome(UNKNOWN_TASK_STATUS_FALLBACK)));
|
|
7097
7168
|
const PriorityField = TaskPriority.pipe(Schema$1.annotateEncoded({ description: "Relative urgency: none, low, medium, high or urgent." }));
|
|
7098
7169
|
const AssigneeField = TrimmedNonEmptyString.check(Schema$1.isMaxLength(TASK_ASSIGNEE_MAX_LENGTH)).pipe(Schema$1.annotateEncoded({ description: "Who owns the task — a person's handle or an agent name." }));
|
|
7099
7170
|
/**
|
|
@@ -7161,7 +7232,7 @@ const Task = Schema$1.Struct({
|
|
|
7161
7232
|
threadId: Schema$1.NullOr(ThreadId),
|
|
7162
7233
|
title: TrimmedNonEmptyString.check(Schema$1.isMaxLength(TASK_TITLE_MAX_LENGTH)),
|
|
7163
7234
|
body: Schema$1.String,
|
|
7164
|
-
status:
|
|
7235
|
+
status: StoredStatusField,
|
|
7165
7236
|
priority: TaskPriority,
|
|
7166
7237
|
assignee: Schema$1.NullOr(TrimmedNonEmptyString.check(Schema$1.isMaxLength(TASK_ASSIGNEE_MAX_LENGTH))),
|
|
7167
7238
|
labels: Schema$1.Array(TaskLabel).check(Schema$1.isMaxLength(TASK_LABELS_MAX_COUNT)),
|
|
@@ -45765,12 +45836,12 @@ function decodeProviderDriverKind(providerName, operation) {
|
|
|
45765
45836
|
cause
|
|
45766
45837
|
})));
|
|
45767
45838
|
}
|
|
45768
|
-
function isRecord$
|
|
45839
|
+
function isRecord$5(value) {
|
|
45769
45840
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
45770
45841
|
}
|
|
45771
45842
|
function mergeRuntimePayload(existing, next) {
|
|
45772
45843
|
if (next === void 0) return existing ?? null;
|
|
45773
|
-
if (isRecord$
|
|
45844
|
+
if (isRecord$5(existing) && isRecord$5(next)) return {
|
|
45774
45845
|
...existing,
|
|
45775
45846
|
...next
|
|
45776
45847
|
};
|
|
@@ -47035,6 +47106,7 @@ function buildServerProvider(input) {
|
|
|
47035
47106
|
...input.presentation.badgeLabel ? { badgeLabel: input.presentation.badgeLabel } : {},
|
|
47036
47107
|
...typeof input.presentation.showInteractionModeToggle === "boolean" ? { showInteractionModeToggle: input.presentation.showInteractionModeToggle } : {},
|
|
47037
47108
|
...typeof input.presentation.requiresNewThreadForModelChange === "boolean" ? { requiresNewThreadForModelChange: input.presentation.requiresNewThreadForModelChange } : {},
|
|
47109
|
+
...input.presentation.supportedRuntimeModes ? { supportedRuntimeModes: input.presentation.supportedRuntimeModes } : {},
|
|
47038
47110
|
enabled: input.enabled,
|
|
47039
47111
|
installed: input.probe.installed,
|
|
47040
47112
|
version: input.probe.version,
|
|
@@ -47491,7 +47563,7 @@ var OpenCodeRuntime = class extends Context.Service()("@p4code/cli/provider/open
|
|
|
47491
47563
|
const OpenCodeRuntimeLive = Layer.effect(OpenCodeRuntime, makeOpenCodeRuntime).pipe(Layer.provide(layer$71));
|
|
47492
47564
|
//#endregion
|
|
47493
47565
|
//#region src/textGeneration/TextGenerationUtils.ts
|
|
47494
|
-
const isTextGenerationError$
|
|
47566
|
+
const isTextGenerationError$3 = Schema$1.is(TextGenerationError);
|
|
47495
47567
|
/** Convert an Effect Schema to a flat JSON Schema object, inlining `$defs` when present. */
|
|
47496
47568
|
function toJsonSchemaObject(schema) {
|
|
47497
47569
|
const document = Schema$1.toJsonSchemaDocument(schema);
|
|
@@ -47536,7 +47608,7 @@ function cliLabel(cliName) {
|
|
|
47536
47608
|
* and Claude (and future providers) can share the same logic.
|
|
47537
47609
|
*/
|
|
47538
47610
|
function normalizeCliError(cliName, operation, error, fallback) {
|
|
47539
|
-
if (isTextGenerationError$
|
|
47611
|
+
if (isTextGenerationError$3(error)) return error;
|
|
47540
47612
|
if (error instanceof Error) {
|
|
47541
47613
|
const lower = error.message.toLowerCase();
|
|
47542
47614
|
if (error.message.includes(`Command not found: ${cliName}`) || lower.includes(`spawn ${cliName}`) || lower.includes("enoent")) return new TextGenerationError({
|
|
@@ -49065,7 +49137,7 @@ function compressTurnReminderFor(mode) {
|
|
|
49065
49137
|
*/
|
|
49066
49138
|
const encodeUnknownJsonStringExit$2 = Schema$1.encodeUnknownExit(Schema$1.UnknownFromJsonString);
|
|
49067
49139
|
const decodeUnknownJsonStringExit = Schema$1.decodeUnknownExit(Schema$1.UnknownFromJsonString);
|
|
49068
|
-
const PROVIDER$
|
|
49140
|
+
const PROVIDER$6 = ProviderDriverKind.make("claudeAgent");
|
|
49069
49141
|
function encodeJsonStringForDiagnostics$2(input) {
|
|
49070
49142
|
const result = encodeUnknownJsonStringExit$2(input);
|
|
49071
49143
|
return Exit.isSuccess(result) ? result.value : void 0;
|
|
@@ -49673,7 +49745,7 @@ const buildUserMessageEffect = Effect.fn("buildUserMessageEffect")(function* (in
|
|
|
49673
49745
|
for (const attachment of input.attachments ?? []) {
|
|
49674
49746
|
if (attachment.type !== "image") continue;
|
|
49675
49747
|
if (!SUPPORTED_CLAUDE_IMAGE_MIME_TYPES.has(attachment.mimeType)) return yield* new ProviderAdapterRequestError({
|
|
49676
|
-
provider: PROVIDER$
|
|
49748
|
+
provider: PROVIDER$6,
|
|
49677
49749
|
method: "turn/start",
|
|
49678
49750
|
detail: `Unsupported Claude image attachment type '${attachment.mimeType}'.`
|
|
49679
49751
|
});
|
|
@@ -49682,12 +49754,12 @@ const buildUserMessageEffect = Effect.fn("buildUserMessageEffect")(function* (in
|
|
|
49682
49754
|
attachment
|
|
49683
49755
|
});
|
|
49684
49756
|
if (!attachmentPath) return yield* new ProviderAdapterRequestError({
|
|
49685
|
-
provider: PROVIDER$
|
|
49757
|
+
provider: PROVIDER$6,
|
|
49686
49758
|
method: "turn/start",
|
|
49687
49759
|
detail: `Invalid attachment id '${attachment.id}'.`
|
|
49688
49760
|
});
|
|
49689
49761
|
const bytes = yield* dependencies.fileSystem.readFile(attachmentPath).pipe(Effect.mapError((cause) => new ProviderAdapterRequestError({
|
|
49690
|
-
provider: PROVIDER$
|
|
49762
|
+
provider: PROVIDER$6,
|
|
49691
49763
|
method: "turn/start",
|
|
49692
49764
|
detail: "Failed to read attachment file.",
|
|
49693
49765
|
cause
|
|
@@ -49785,12 +49857,12 @@ function toolResultBlocksFromUserMessage(message) {
|
|
|
49785
49857
|
function toSessionError(threadId, cause) {
|
|
49786
49858
|
const normalized = toMessage(cause, "").toLowerCase();
|
|
49787
49859
|
if (normalized.includes("unknown session") || normalized.includes("not found")) return new ProviderAdapterSessionNotFoundError({
|
|
49788
|
-
provider: PROVIDER$
|
|
49860
|
+
provider: PROVIDER$6,
|
|
49789
49861
|
threadId,
|
|
49790
49862
|
cause
|
|
49791
49863
|
});
|
|
49792
49864
|
if (normalized.includes("closed")) return new ProviderAdapterSessionClosedError({
|
|
49793
|
-
provider: PROVIDER$
|
|
49865
|
+
provider: PROVIDER$6,
|
|
49794
49866
|
threadId,
|
|
49795
49867
|
cause
|
|
49796
49868
|
});
|
|
@@ -49799,7 +49871,7 @@ function toRequestError$1(threadId, method, cause) {
|
|
|
49799
49871
|
const sessionError = toSessionError(threadId, cause);
|
|
49800
49872
|
if (sessionError) return sessionError;
|
|
49801
49873
|
return new ProviderAdapterRequestError({
|
|
49802
|
-
provider: PROVIDER$
|
|
49874
|
+
provider: PROVIDER$6,
|
|
49803
49875
|
method,
|
|
49804
49876
|
detail: `${method} failed`,
|
|
49805
49877
|
cause
|
|
@@ -49899,7 +49971,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
49899
49971
|
const runtimeEventQueue = yield* Queue.unbounded();
|
|
49900
49972
|
const nowIso = Effect.map(DateTime.now, DateTime.formatIso);
|
|
49901
49973
|
const randomUUIDv4 = crypto.randomUUIDv4.pipe(Effect.mapError((cause) => new ProviderAdapterRequestError({
|
|
49902
|
-
provider: PROVIDER$
|
|
49974
|
+
provider: PROVIDER$6,
|
|
49903
49975
|
method: "crypto/randomUUIDv4",
|
|
49904
49976
|
detail: "Failed to generate Claude runtime identifier.",
|
|
49905
49977
|
cause
|
|
@@ -49919,7 +49991,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
49919
49991
|
event: {
|
|
49920
49992
|
id: "uuid" in message && typeof message.uuid === "string" ? message.uuid : yield* randomUUIDv4,
|
|
49921
49993
|
kind: "notification",
|
|
49922
|
-
provider: PROVIDER$
|
|
49994
|
+
provider: PROVIDER$6,
|
|
49923
49995
|
createdAt: observedAt,
|
|
49924
49996
|
method: sdkNativeMethod(message),
|
|
49925
49997
|
...typeof message.session_id === "string" ? { providerThreadId: message.session_id } : {},
|
|
@@ -49932,7 +50004,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
49932
50004
|
const snapshotThread = Effect.fn("snapshotThread")(function* (context) {
|
|
49933
50005
|
const threadId = context.session.threadId;
|
|
49934
50006
|
if (!threadId) return yield* new ProviderAdapterValidationError({
|
|
49935
|
-
provider: PROVIDER$
|
|
50007
|
+
provider: PROVIDER$6,
|
|
49936
50008
|
operation: "readThread",
|
|
49937
50009
|
issue: "Session thread id is not initialized yet."
|
|
49938
50010
|
});
|
|
@@ -50005,7 +50077,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50005
50077
|
yield* offerRuntimeEvent({
|
|
50006
50078
|
type: "content.delta",
|
|
50007
50079
|
eventId: deltaStamp.eventId,
|
|
50008
|
-
provider: PROVIDER$
|
|
50080
|
+
provider: PROVIDER$6,
|
|
50009
50081
|
createdAt: deltaStamp.createdAt,
|
|
50010
50082
|
threadId: context.session.threadId,
|
|
50011
50083
|
turnId: turnState.turnId,
|
|
@@ -50028,7 +50100,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50028
50100
|
yield* offerRuntimeEvent({
|
|
50029
50101
|
type: "item.completed",
|
|
50030
50102
|
eventId: stamp.eventId,
|
|
50031
|
-
provider: PROVIDER$
|
|
50103
|
+
provider: PROVIDER$6,
|
|
50032
50104
|
createdAt: stamp.createdAt,
|
|
50033
50105
|
itemId: asRuntimeItemId$1(block.itemId),
|
|
50034
50106
|
threadId: context.session.threadId,
|
|
@@ -50082,7 +50154,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50082
50154
|
yield* offerRuntimeEvent({
|
|
50083
50155
|
type: "thread.started",
|
|
50084
50156
|
eventId: stamp.eventId,
|
|
50085
|
-
provider: PROVIDER$
|
|
50157
|
+
provider: PROVIDER$6,
|
|
50086
50158
|
createdAt: stamp.createdAt,
|
|
50087
50159
|
threadId: context.session.threadId,
|
|
50088
50160
|
payload: { providerThreadId: nextThreadId },
|
|
@@ -50102,7 +50174,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50102
50174
|
yield* offerRuntimeEvent({
|
|
50103
50175
|
type: "runtime.error",
|
|
50104
50176
|
eventId: stamp.eventId,
|
|
50105
|
-
provider: PROVIDER$
|
|
50177
|
+
provider: PROVIDER$6,
|
|
50106
50178
|
createdAt: stamp.createdAt,
|
|
50107
50179
|
threadId: context.session.threadId,
|
|
50108
50180
|
...turnState ? { turnId: asCanonicalTurnId(turnState.turnId) } : {},
|
|
@@ -50120,7 +50192,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50120
50192
|
yield* offerRuntimeEvent({
|
|
50121
50193
|
type: "runtime.warning",
|
|
50122
50194
|
eventId: stamp.eventId,
|
|
50123
|
-
provider: PROVIDER$
|
|
50195
|
+
provider: PROVIDER$6,
|
|
50124
50196
|
createdAt: stamp.createdAt,
|
|
50125
50197
|
threadId: context.session.threadId,
|
|
50126
50198
|
...turnState ? { turnId: asCanonicalTurnId(turnState.turnId) } : {},
|
|
@@ -50140,7 +50212,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50140
50212
|
yield* offerRuntimeEvent({
|
|
50141
50213
|
type: "thread.token-usage.updated",
|
|
50142
50214
|
eventId: stamp.eventId,
|
|
50143
|
-
provider: PROVIDER$
|
|
50215
|
+
provider: PROVIDER$6,
|
|
50144
50216
|
createdAt: stamp.createdAt,
|
|
50145
50217
|
threadId: context.session.threadId,
|
|
50146
50218
|
...turnState ? { turnId: turnState.turnId } : {},
|
|
@@ -50193,7 +50265,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50193
50265
|
yield* offerRuntimeEvent({
|
|
50194
50266
|
type: "turn.proposed.completed",
|
|
50195
50267
|
eventId: stamp.eventId,
|
|
50196
|
-
provider: PROVIDER$
|
|
50268
|
+
provider: PROVIDER$6,
|
|
50197
50269
|
createdAt: stamp.createdAt,
|
|
50198
50270
|
threadId: context.session.threadId,
|
|
50199
50271
|
turnId: turnState.turnId,
|
|
@@ -50213,7 +50285,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50213
50285
|
yield* offerRuntimeEvent({
|
|
50214
50286
|
type: "turn.plan.updated",
|
|
50215
50287
|
eventId: stamp.eventId,
|
|
50216
|
-
provider: PROVIDER$
|
|
50288
|
+
provider: PROVIDER$6,
|
|
50217
50289
|
createdAt: stamp.createdAt,
|
|
50218
50290
|
threadId: context.session.threadId,
|
|
50219
50291
|
...context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {},
|
|
@@ -50261,7 +50333,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50261
50333
|
yield* offerRuntimeEvent({
|
|
50262
50334
|
type: "turn.completed",
|
|
50263
50335
|
eventId: stamp.eventId,
|
|
50264
|
-
provider: PROVIDER$
|
|
50336
|
+
provider: PROVIDER$6,
|
|
50265
50337
|
createdAt: stamp.createdAt,
|
|
50266
50338
|
threadId: context.session.threadId,
|
|
50267
50339
|
payload: {
|
|
@@ -50281,7 +50353,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50281
50353
|
yield* offerRuntimeEvent({
|
|
50282
50354
|
type: "item.completed",
|
|
50283
50355
|
eventId: toolStamp.eventId,
|
|
50284
|
-
provider: PROVIDER$
|
|
50356
|
+
provider: PROVIDER$6,
|
|
50285
50357
|
createdAt: toolStamp.createdAt,
|
|
50286
50358
|
threadId: context.session.threadId,
|
|
50287
50359
|
turnId: turnState.turnId,
|
|
@@ -50324,7 +50396,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50324
50396
|
yield* offerRuntimeEvent({
|
|
50325
50397
|
type: "turn.completed",
|
|
50326
50398
|
eventId: stamp.eventId,
|
|
50327
|
-
provider: PROVIDER$
|
|
50399
|
+
provider: PROVIDER$6,
|
|
50328
50400
|
createdAt: stamp.createdAt,
|
|
50329
50401
|
threadId: context.session.threadId,
|
|
50330
50402
|
turnId: turnState.turnId,
|
|
@@ -50398,7 +50470,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50398
50470
|
yield* offerRuntimeEvent({
|
|
50399
50471
|
type: "turn.started",
|
|
50400
50472
|
eventId: turnStartedStamp.eventId,
|
|
50401
|
-
provider: PROVIDER$
|
|
50473
|
+
provider: PROVIDER$6,
|
|
50402
50474
|
createdAt: turnStartedStamp.createdAt,
|
|
50403
50475
|
threadId: context.session.threadId,
|
|
50404
50476
|
turnId,
|
|
@@ -50478,7 +50550,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50478
50550
|
yield* offerRuntimeEvent({
|
|
50479
50551
|
type: "content.delta",
|
|
50480
50552
|
eventId: stamp.eventId,
|
|
50481
|
-
provider: PROVIDER$
|
|
50553
|
+
provider: PROVIDER$6,
|
|
50482
50554
|
createdAt: stamp.createdAt,
|
|
50483
50555
|
threadId: context.session.threadId,
|
|
50484
50556
|
turnId: context.turnState.turnId,
|
|
@@ -50522,7 +50594,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50522
50594
|
yield* offerRuntimeEvent({
|
|
50523
50595
|
type: "item.updated",
|
|
50524
50596
|
eventId: stamp.eventId,
|
|
50525
|
-
provider: PROVIDER$
|
|
50597
|
+
provider: PROVIDER$6,
|
|
50526
50598
|
createdAt: stamp.createdAt,
|
|
50527
50599
|
threadId: context.session.threadId,
|
|
50528
50600
|
...context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {},
|
|
@@ -50552,7 +50624,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50552
50624
|
yield* offerRuntimeEvent({
|
|
50553
50625
|
type: "turn.plan.updated",
|
|
50554
50626
|
eventId: planStamp.eventId,
|
|
50555
|
-
provider: PROVIDER$
|
|
50627
|
+
provider: PROVIDER$6,
|
|
50556
50628
|
createdAt: planStamp.createdAt,
|
|
50557
50629
|
threadId: context.session.threadId,
|
|
50558
50630
|
...context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {},
|
|
@@ -50592,7 +50664,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50592
50664
|
yield* offerRuntimeEvent({
|
|
50593
50665
|
type: "item.started",
|
|
50594
50666
|
eventId: stamp.eventId,
|
|
50595
|
-
provider: PROVIDER$
|
|
50667
|
+
provider: PROVIDER$6,
|
|
50596
50668
|
createdAt: stamp.createdAt,
|
|
50597
50669
|
threadId: context.session.threadId,
|
|
50598
50670
|
...context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {},
|
|
@@ -50650,7 +50722,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50650
50722
|
yield* offerRuntimeEvent({
|
|
50651
50723
|
type: "item.updated",
|
|
50652
50724
|
eventId: updatedStamp.eventId,
|
|
50653
|
-
provider: PROVIDER$
|
|
50725
|
+
provider: PROVIDER$6,
|
|
50654
50726
|
createdAt: updatedStamp.createdAt,
|
|
50655
50727
|
threadId: context.session.threadId,
|
|
50656
50728
|
...context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {},
|
|
@@ -50675,7 +50747,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50675
50747
|
yield* offerRuntimeEvent({
|
|
50676
50748
|
type: "content.delta",
|
|
50677
50749
|
eventId: deltaStamp.eventId,
|
|
50678
|
-
provider: PROVIDER$
|
|
50750
|
+
provider: PROVIDER$6,
|
|
50679
50751
|
createdAt: deltaStamp.createdAt,
|
|
50680
50752
|
threadId: context.session.threadId,
|
|
50681
50753
|
turnId: context.turnState.turnId,
|
|
@@ -50696,7 +50768,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50696
50768
|
yield* offerRuntimeEvent({
|
|
50697
50769
|
type: "item.completed",
|
|
50698
50770
|
eventId: completedStamp.eventId,
|
|
50699
|
-
provider: PROVIDER$
|
|
50771
|
+
provider: PROVIDER$6,
|
|
50700
50772
|
createdAt: completedStamp.createdAt,
|
|
50701
50773
|
threadId: context.session.threadId,
|
|
50702
50774
|
...context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {},
|
|
@@ -50748,7 +50820,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50748
50820
|
yield* offerRuntimeEvent({
|
|
50749
50821
|
type: "turn.started",
|
|
50750
50822
|
eventId: turnStartedStamp.eventId,
|
|
50751
|
-
provider: PROVIDER$
|
|
50823
|
+
provider: PROVIDER$6,
|
|
50752
50824
|
createdAt: turnStartedStamp.createdAt,
|
|
50753
50825
|
threadId: context.session.threadId,
|
|
50754
50826
|
turnId,
|
|
@@ -50801,7 +50873,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50801
50873
|
const stamp = yield* makeEventStamp();
|
|
50802
50874
|
const base = {
|
|
50803
50875
|
eventId: stamp.eventId,
|
|
50804
|
-
provider: PROVIDER$
|
|
50876
|
+
provider: PROVIDER$6,
|
|
50805
50877
|
createdAt: stamp.createdAt,
|
|
50806
50878
|
threadId: context.session.threadId,
|
|
50807
50879
|
...context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {},
|
|
@@ -50891,7 +50963,9 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50891
50963
|
payload: {
|
|
50892
50964
|
taskId: RuntimeTaskId.make(message.task_id),
|
|
50893
50965
|
description: message.description,
|
|
50894
|
-
...message.task_type ? { taskType: message.task_type } : {}
|
|
50966
|
+
...message.task_type ? { taskType: message.task_type } : {},
|
|
50967
|
+
...message.tool_use_id ? { toolUseId: message.tool_use_id } : {},
|
|
50968
|
+
...message.subagent_type ? { subagentType: message.subagent_type } : {}
|
|
50895
50969
|
}
|
|
50896
50970
|
});
|
|
50897
50971
|
return;
|
|
@@ -50908,7 +50982,9 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50908
50982
|
description: message.description,
|
|
50909
50983
|
...message.summary ? { summary: message.summary } : {},
|
|
50910
50984
|
...message.usage ? { usage: message.usage } : {},
|
|
50911
|
-
...message.last_tool_name ? { lastToolName: message.last_tool_name } : {}
|
|
50985
|
+
...message.last_tool_name ? { lastToolName: message.last_tool_name } : {},
|
|
50986
|
+
...message.tool_use_id ? { toolUseId: message.tool_use_id } : {},
|
|
50987
|
+
...message.subagent_type ? { subagentType: message.subagent_type } : {}
|
|
50912
50988
|
}
|
|
50913
50989
|
});
|
|
50914
50990
|
return;
|
|
@@ -50925,7 +51001,8 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50925
51001
|
taskId: RuntimeTaskId.make(message.task_id),
|
|
50926
51002
|
status: message.status,
|
|
50927
51003
|
...message.summary ? { summary: message.summary } : {},
|
|
50928
|
-
...message.usage ? { usage: message.usage } : {}
|
|
51004
|
+
...message.usage ? { usage: message.usage } : {},
|
|
51005
|
+
...message.tool_use_id ? { toolUseId: message.tool_use_id } : {}
|
|
50929
51006
|
}
|
|
50930
51007
|
});
|
|
50931
51008
|
return;
|
|
@@ -50999,7 +51076,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
50999
51076
|
const stamp = yield* makeEventStamp();
|
|
51000
51077
|
const base = {
|
|
51001
51078
|
eventId: stamp.eventId,
|
|
51002
|
-
provider: PROVIDER$
|
|
51079
|
+
provider: PROVIDER$6,
|
|
51003
51080
|
createdAt: stamp.createdAt,
|
|
51004
51081
|
threadId: context.session.threadId,
|
|
51005
51082
|
...context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {},
|
|
@@ -51089,12 +51166,12 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51089
51166
|
}
|
|
51090
51167
|
});
|
|
51091
51168
|
const runSdkStream = (context) => Stream.fromAsyncIterable(context.query, (cause) => new ProviderAdapterProcessError({
|
|
51092
|
-
provider: PROVIDER$
|
|
51169
|
+
provider: PROVIDER$6,
|
|
51093
51170
|
threadId: context.session.threadId,
|
|
51094
51171
|
detail: "Claude runtime stream failed.",
|
|
51095
51172
|
cause
|
|
51096
51173
|
})).pipe(Stream.takeWhile(() => !context.stopped), Stream.runForEach((message) => handleSdkMessage(context, message).pipe(Effect.mapError((cause) => new ProviderAdapterProcessError({
|
|
51097
|
-
provider: PROVIDER$
|
|
51174
|
+
provider: PROVIDER$6,
|
|
51098
51175
|
threadId: context.session.threadId,
|
|
51099
51176
|
detail: "Failed to process Claude runtime event.",
|
|
51100
51177
|
cause
|
|
@@ -51124,7 +51201,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51124
51201
|
yield* offerRuntimeEvent({
|
|
51125
51202
|
type: "request.resolved",
|
|
51126
51203
|
eventId: stamp.eventId,
|
|
51127
|
-
provider: PROVIDER$
|
|
51204
|
+
provider: PROVIDER$6,
|
|
51128
51205
|
createdAt: stamp.createdAt,
|
|
51129
51206
|
threadId: context.session.threadId,
|
|
51130
51207
|
...context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {},
|
|
@@ -51145,7 +51222,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51145
51222
|
yield* Effect.try({
|
|
51146
51223
|
try: () => context.query.close(),
|
|
51147
51224
|
catch: (cause) => new ProviderAdapterProcessError({
|
|
51148
|
-
provider: PROVIDER$
|
|
51225
|
+
provider: PROVIDER$6,
|
|
51149
51226
|
threadId: context.session.threadId,
|
|
51150
51227
|
detail: "Failed to close Claude runtime query.",
|
|
51151
51228
|
cause
|
|
@@ -51168,7 +51245,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51168
51245
|
yield* offerRuntimeEvent({
|
|
51169
51246
|
type: "session.exited",
|
|
51170
51247
|
eventId: stamp.eventId,
|
|
51171
|
-
provider: PROVIDER$
|
|
51248
|
+
provider: PROVIDER$6,
|
|
51172
51249
|
createdAt: stamp.createdAt,
|
|
51173
51250
|
threadId: context.session.threadId,
|
|
51174
51251
|
payload: {
|
|
@@ -51183,20 +51260,20 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51183
51260
|
const requireSession = (threadId) => {
|
|
51184
51261
|
const context = sessions.get(threadId);
|
|
51185
51262
|
if (!context) return Effect.fail(new ProviderAdapterSessionNotFoundError({
|
|
51186
|
-
provider: PROVIDER$
|
|
51263
|
+
provider: PROVIDER$6,
|
|
51187
51264
|
threadId
|
|
51188
51265
|
}));
|
|
51189
51266
|
if (context.stopped || context.session.status === "closed") return Effect.fail(new ProviderAdapterSessionClosedError({
|
|
51190
|
-
provider: PROVIDER$
|
|
51267
|
+
provider: PROVIDER$6,
|
|
51191
51268
|
threadId
|
|
51192
51269
|
}));
|
|
51193
51270
|
return Effect.succeed(context);
|
|
51194
51271
|
};
|
|
51195
51272
|
const startSession = Effect.fn("startSession")(function* (input) {
|
|
51196
|
-
if (input.provider !== void 0 && input.provider !== PROVIDER$
|
|
51197
|
-
provider: PROVIDER$
|
|
51273
|
+
if (input.provider !== void 0 && input.provider !== PROVIDER$6) return yield* new ProviderAdapterValidationError({
|
|
51274
|
+
provider: PROVIDER$6,
|
|
51198
51275
|
operation: "startSession",
|
|
51199
|
-
issue: `Expected provider '${PROVIDER$
|
|
51276
|
+
issue: `Expected provider '${PROVIDER$6}' but received '${input.provider}'.`
|
|
51200
51277
|
});
|
|
51201
51278
|
const existingContext = sessions.get(input.threadId);
|
|
51202
51279
|
if (existingContext) {
|
|
@@ -51252,7 +51329,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51252
51329
|
yield* offerRuntimeEvent({
|
|
51253
51330
|
type: "user-input.requested",
|
|
51254
51331
|
eventId: requestedStamp.eventId,
|
|
51255
|
-
provider: PROVIDER$
|
|
51332
|
+
provider: PROVIDER$6,
|
|
51256
51333
|
createdAt: requestedStamp.createdAt,
|
|
51257
51334
|
threadId: context.session.threadId,
|
|
51258
51335
|
...context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {},
|
|
@@ -51282,7 +51359,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51282
51359
|
yield* offerRuntimeEvent({
|
|
51283
51360
|
type: "user-input.resolved",
|
|
51284
51361
|
eventId: resolvedStamp.eventId,
|
|
51285
|
-
provider: PROVIDER$
|
|
51362
|
+
provider: PROVIDER$6,
|
|
51286
51363
|
createdAt: resolvedStamp.createdAt,
|
|
51287
51364
|
threadId: context.session.threadId,
|
|
51288
51365
|
...context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {},
|
|
@@ -51349,7 +51426,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51349
51426
|
yield* offerRuntimeEvent({
|
|
51350
51427
|
type: "request.opened",
|
|
51351
51428
|
eventId: requestedStamp.eventId,
|
|
51352
|
-
provider: PROVIDER$
|
|
51429
|
+
provider: PROVIDER$6,
|
|
51353
51430
|
createdAt: requestedStamp.createdAt,
|
|
51354
51431
|
threadId: context.session.threadId,
|
|
51355
51432
|
...context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {},
|
|
@@ -51386,7 +51463,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51386
51463
|
yield* offerRuntimeEvent({
|
|
51387
51464
|
type: "request.resolved",
|
|
51388
51465
|
eventId: resolvedStamp.eventId,
|
|
51389
|
-
provider: PROVIDER$
|
|
51466
|
+
provider: PROVIDER$6,
|
|
51390
51467
|
createdAt: resolvedStamp.createdAt,
|
|
51391
51468
|
threadId: context.session.threadId,
|
|
51392
51469
|
...context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {},
|
|
@@ -51476,7 +51553,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51476
51553
|
} } : {}
|
|
51477
51554
|
};
|
|
51478
51555
|
yield* Effect.annotateCurrentSpan({
|
|
51479
|
-
"provider.kind": PROVIDER$
|
|
51556
|
+
"provider.kind": PROVIDER$6,
|
|
51480
51557
|
"provider.thread_id": threadId,
|
|
51481
51558
|
"provider.runtime_mode": input.runtimeMode,
|
|
51482
51559
|
"claude.resume.source": existingResumeSessionId !== void 0 ? "resume-session" : "generated-session",
|
|
@@ -51505,7 +51582,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51505
51582
|
options: queryOptions
|
|
51506
51583
|
}),
|
|
51507
51584
|
catch: (cause) => new ProviderAdapterProcessError({
|
|
51508
|
-
provider: PROVIDER$
|
|
51585
|
+
provider: PROVIDER$6,
|
|
51509
51586
|
threadId,
|
|
51510
51587
|
detail: "Failed to start Claude runtime session.",
|
|
51511
51588
|
cause
|
|
@@ -51513,7 +51590,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51513
51590
|
});
|
|
51514
51591
|
const session = {
|
|
51515
51592
|
threadId,
|
|
51516
|
-
provider: PROVIDER$
|
|
51593
|
+
provider: PROVIDER$6,
|
|
51517
51594
|
providerInstanceId: boundInstanceId,
|
|
51518
51595
|
status: "ready",
|
|
51519
51596
|
runtimeMode: input.runtimeMode,
|
|
@@ -51560,7 +51637,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51560
51637
|
yield* offerRuntimeEvent({
|
|
51561
51638
|
type: "session.started",
|
|
51562
51639
|
eventId: sessionStartedStamp.eventId,
|
|
51563
|
-
provider: PROVIDER$
|
|
51640
|
+
provider: PROVIDER$6,
|
|
51564
51641
|
createdAt: sessionStartedStamp.createdAt,
|
|
51565
51642
|
threadId,
|
|
51566
51643
|
payload: input.resumeCursor !== void 0 ? { resume: input.resumeCursor } : {},
|
|
@@ -51570,7 +51647,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51570
51647
|
yield* offerRuntimeEvent({
|
|
51571
51648
|
type: "session.configured",
|
|
51572
51649
|
eventId: configuredStamp.eventId,
|
|
51573
|
-
provider: PROVIDER$
|
|
51650
|
+
provider: PROVIDER$6,
|
|
51574
51651
|
createdAt: configuredStamp.createdAt,
|
|
51575
51652
|
threadId,
|
|
51576
51653
|
payload: { config: {
|
|
@@ -51586,7 +51663,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51586
51663
|
yield* offerRuntimeEvent({
|
|
51587
51664
|
type: "session.state.changed",
|
|
51588
51665
|
eventId: readyStamp.eventId,
|
|
51589
|
-
provider: PROVIDER$
|
|
51666
|
+
provider: PROVIDER$6,
|
|
51590
51667
|
createdAt: readyStamp.createdAt,
|
|
51591
51668
|
threadId,
|
|
51592
51669
|
payload: { state: "ready" },
|
|
@@ -51667,7 +51744,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51667
51744
|
const context = yield* requireSession(threadId);
|
|
51668
51745
|
const pending = context.pendingApprovals.get(requestId);
|
|
51669
51746
|
if (!pending) return yield* new ProviderAdapterRequestError({
|
|
51670
|
-
provider: PROVIDER$
|
|
51747
|
+
provider: PROVIDER$6,
|
|
51671
51748
|
method: "item/requestApproval/decision",
|
|
51672
51749
|
detail: `Unknown pending approval request: ${requestId}`
|
|
51673
51750
|
});
|
|
@@ -51678,7 +51755,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51678
51755
|
const context = yield* requireSession(threadId);
|
|
51679
51756
|
const pending = context.pendingUserInputs.get(requestId);
|
|
51680
51757
|
if (!pending) return yield* new ProviderAdapterRequestError({
|
|
51681
|
-
provider: PROVIDER$
|
|
51758
|
+
provider: PROVIDER$6,
|
|
51682
51759
|
method: "item/tool/respondToUserInput",
|
|
51683
51760
|
detail: `Unknown pending user-input request: ${requestId}`
|
|
51684
51761
|
});
|
|
@@ -51697,7 +51774,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
51697
51774
|
const stopAll = () => Effect.forEach(sessions, ([, context]) => stopSessionInternal(context, { emitExitEvent: true }), { discard: true });
|
|
51698
51775
|
yield* Effect.addFinalizer(() => Effect.forEach(sessions, ([, context]) => stopSessionInternal(context, { emitExitEvent: false }), { discard: true }).pipe(Effect.catch((cause) => Effect.logError("Failed to emit Claude session shutdown event.", { cause })), Effect.tap(() => Queue.shutdown(runtimeEventQueue))));
|
|
51699
51776
|
return {
|
|
51700
|
-
provider: PROVIDER$
|
|
51777
|
+
provider: PROVIDER$6,
|
|
51701
51778
|
capabilities: { sessionModelSwitch: "in-session" },
|
|
51702
51779
|
startSession,
|
|
51703
51780
|
sendTurn,
|
|
@@ -51841,15 +51918,15 @@ function makeProviderSnapshotSettingsSource(provider, serverSettings) {
|
|
|
51841
51918
|
* @module provider/Drivers/ClaudeDriver
|
|
51842
51919
|
*/
|
|
51843
51920
|
const decodeClaudeSettings = Schema$1.decodeSync(ClaudeSettings);
|
|
51844
|
-
const DRIVER_KIND$
|
|
51845
|
-
const SNAPSHOT_REFRESH_INTERVAL$
|
|
51921
|
+
const DRIVER_KIND$5 = ProviderDriverKind.make("claudeAgent");
|
|
51922
|
+
const SNAPSHOT_REFRESH_INTERVAL$5 = Duration.minutes(5);
|
|
51846
51923
|
const CAPABILITIES_PROBE_TTL = Duration.minutes(5);
|
|
51847
51924
|
function isClaudeNativeCommandPath(commandPath) {
|
|
51848
51925
|
const normalized = normalizeCommandPath(commandPath);
|
|
51849
51926
|
return normalized.endsWith("/.local/bin/claude") || normalized.endsWith("/.local/bin/claude.exe") || normalized.includes("/.local/share/claude/");
|
|
51850
51927
|
}
|
|
51851
|
-
const UPDATE$
|
|
51852
|
-
provider: DRIVER_KIND$
|
|
51928
|
+
const UPDATE$5 = makePackageManagedProviderMaintenanceResolver({
|
|
51929
|
+
provider: DRIVER_KIND$5,
|
|
51853
51930
|
npmPackageName: "@anthropic-ai/claude-code",
|
|
51854
51931
|
homebrewFormula: "claude-code",
|
|
51855
51932
|
nativeUpdate: {
|
|
@@ -51859,16 +51936,16 @@ const UPDATE$4 = makePackageManagedProviderMaintenanceResolver({
|
|
|
51859
51936
|
isCommandPath: isClaudeNativeCommandPath
|
|
51860
51937
|
}
|
|
51861
51938
|
});
|
|
51862
|
-
const withInstanceIdentity$
|
|
51939
|
+
const withInstanceIdentity$5 = (input) => (snapshot) => ({
|
|
51863
51940
|
...snapshot,
|
|
51864
51941
|
instanceId: input.instanceId,
|
|
51865
|
-
driver: DRIVER_KIND$
|
|
51942
|
+
driver: DRIVER_KIND$5,
|
|
51866
51943
|
...input.displayName ? { displayName: input.displayName } : {},
|
|
51867
51944
|
...input.accentColor ? { accentColor: input.accentColor } : {},
|
|
51868
51945
|
continuation: { groupKey: input.continuationGroupKey }
|
|
51869
51946
|
});
|
|
51870
51947
|
const ClaudeDriver = {
|
|
51871
|
-
driverKind: DRIVER_KIND$
|
|
51948
|
+
driverKind: DRIVER_KIND$5,
|
|
51872
51949
|
metadata: {
|
|
51873
51950
|
displayName: "Claude",
|
|
51874
51951
|
supportsMultipleInstances: true
|
|
@@ -51885,19 +51962,19 @@ const ClaudeDriver = {
|
|
|
51885
51962
|
const eventLoggers = yield* ProviderEventLoggers;
|
|
51886
51963
|
const processEnv = mergeProviderInstanceEnvironment(environment);
|
|
51887
51964
|
const fallbackContinuationIdentity = defaultProviderContinuationIdentity({
|
|
51888
|
-
driverKind: DRIVER_KIND$
|
|
51965
|
+
driverKind: DRIVER_KIND$5,
|
|
51889
51966
|
instanceId
|
|
51890
51967
|
});
|
|
51891
51968
|
const effectiveConfig = {
|
|
51892
51969
|
...config,
|
|
51893
51970
|
enabled
|
|
51894
51971
|
};
|
|
51895
|
-
const maintenanceCapabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(UPDATE$
|
|
51972
|
+
const maintenanceCapabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(UPDATE$5, {
|
|
51896
51973
|
binaryPath: effectiveConfig.binaryPath,
|
|
51897
51974
|
env: processEnv
|
|
51898
51975
|
});
|
|
51899
51976
|
const continuationGroupKey = yield* makeClaudeContinuationGroupKey(effectiveConfig);
|
|
51900
|
-
const stampIdentity = withInstanceIdentity$
|
|
51977
|
+
const stampIdentity = withInstanceIdentity$5({
|
|
51901
51978
|
instanceId,
|
|
51902
51979
|
displayName,
|
|
51903
51980
|
accentColor,
|
|
@@ -51931,16 +52008,16 @@ const ClaudeDriver = {
|
|
|
51931
52008
|
initialSnapshot: (settings) => makePendingClaudeProvider(settings.provider).pipe(Effect.map(stampIdentity)),
|
|
51932
52009
|
checkProvider,
|
|
51933
52010
|
enrichSnapshot: ({ settings, snapshot, publishSnapshot }) => enrichProviderSnapshotWithVersionAdvisory(snapshot, maintenanceCapabilities, { enableProviderUpdateChecks: settings.enableProviderUpdateChecks }).pipe(Effect.provideService(HttpClient.HttpClient, httpClient), Effect.flatMap((enrichedSnapshot) => publishSnapshot(enrichedSnapshot))),
|
|
51934
|
-
refreshInterval: SNAPSHOT_REFRESH_INTERVAL$
|
|
52011
|
+
refreshInterval: SNAPSHOT_REFRESH_INTERVAL$5
|
|
51935
52012
|
}).pipe(Effect.mapError((cause) => new ProviderDriverError({
|
|
51936
|
-
driver: DRIVER_KIND$
|
|
52013
|
+
driver: DRIVER_KIND$5,
|
|
51937
52014
|
instanceId,
|
|
51938
52015
|
detail: `Failed to build Claude snapshot: ${cause.message ?? String(cause)}`,
|
|
51939
52016
|
cause
|
|
51940
52017
|
})));
|
|
51941
52018
|
return {
|
|
51942
52019
|
instanceId,
|
|
51943
|
-
driverKind: DRIVER_KIND$
|
|
52020
|
+
driverKind: DRIVER_KIND$5,
|
|
51944
52021
|
continuationIdentity: {
|
|
51945
52022
|
...fallbackContinuationIdentity,
|
|
51946
52023
|
continuationKey: continuationGroupKey
|
|
@@ -70774,7 +70851,7 @@ function buildCodexDeveloperInstructions(interactionMode, runtime, compressMode)
|
|
|
70774
70851
|
//#endregion
|
|
70775
70852
|
//#region src/provider/Layers/CodexSessionRuntime.ts
|
|
70776
70853
|
const decodeV2TurnStartResponse = Schema$1.decodeUnknownEffect(V2TurnStartResponse);
|
|
70777
|
-
const PROVIDER$
|
|
70854
|
+
const PROVIDER$5 = ProviderDriverKind.make("codex");
|
|
70778
70855
|
const ANSI_ESCAPE_REGEX = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
|
|
70779
70856
|
const CODEX_STDERR_LOG_REGEX = /^\d{4}-\d{2}-\d{2}T\S+\s+(TRACE|DEBUG|INFO|WARN|ERROR)\s+\S+:\s+(.*)$/;
|
|
70780
70857
|
const BENIGN_ERROR_LOG_SNIPPETS = ["state db missing rollout path for thread", "state db record_discrepancy: find_thread_path_by_id_str_in_subdir, falling_back"];
|
|
@@ -71126,7 +71203,7 @@ const makeCodexSessionRuntime = (options) => Effect.gen(function* () {
|
|
|
71126
71203
|
})));
|
|
71127
71204
|
const sessionCreatedAt = yield* nowIso;
|
|
71128
71205
|
const initialSession = {
|
|
71129
|
-
provider: PROVIDER$
|
|
71206
|
+
provider: PROVIDER$5,
|
|
71130
71207
|
...options.providerInstanceId ? { providerInstanceId: options.providerInstanceId } : {},
|
|
71131
71208
|
status: "connecting",
|
|
71132
71209
|
runtimeMode: options.runtimeMode,
|
|
@@ -71143,7 +71220,7 @@ const makeCodexSessionRuntime = (options) => Effect.gen(function* () {
|
|
|
71143
71220
|
const id = yield* randomUUIDv4("provider-event");
|
|
71144
71221
|
return yield* offerEvent({
|
|
71145
71222
|
id: EventId.make(id),
|
|
71146
|
-
provider: PROVIDER$
|
|
71223
|
+
provider: PROVIDER$5,
|
|
71147
71224
|
...options.providerInstanceId ? { providerInstanceId: options.providerInstanceId } : {},
|
|
71148
71225
|
createdAt: yield* nowIso,
|
|
71149
71226
|
...event
|
|
@@ -71548,20 +71625,20 @@ const isCodexAppServerProcessExitedError = Schema$1.is(CodexAppServerProcessExit
|
|
|
71548
71625
|
const isCodexAppServerTransportError = Schema$1.is(CodexAppServerTransportError);
|
|
71549
71626
|
const isCodexSessionRuntimeThreadIdMissingError = Schema$1.is(CodexSessionRuntimeThreadIdMissingError);
|
|
71550
71627
|
const isCodexResumeCursorSchema = Schema$1.is(CodexResumeCursorSchema);
|
|
71551
|
-
const PROVIDER$
|
|
71628
|
+
const PROVIDER$4 = ProviderDriverKind.make("codex");
|
|
71552
71629
|
function mapCodexRuntimeError(threadId, method, error) {
|
|
71553
71630
|
if (isCodexAppServerProcessExitedError(error) || isCodexAppServerTransportError(error)) return new ProviderAdapterSessionClosedError({
|
|
71554
|
-
provider: PROVIDER$
|
|
71631
|
+
provider: PROVIDER$4,
|
|
71555
71632
|
threadId,
|
|
71556
71633
|
cause: error
|
|
71557
71634
|
});
|
|
71558
71635
|
if (isCodexSessionRuntimeThreadIdMissingError(error)) return new ProviderAdapterSessionNotFoundError({
|
|
71559
|
-
provider: PROVIDER$
|
|
71636
|
+
provider: PROVIDER$4,
|
|
71560
71637
|
threadId,
|
|
71561
71638
|
cause: error
|
|
71562
71639
|
});
|
|
71563
71640
|
return new ProviderAdapterRequestError({
|
|
71564
|
-
provider: PROVIDER$
|
|
71641
|
+
provider: PROVIDER$4,
|
|
71565
71642
|
method,
|
|
71566
71643
|
detail: error.message,
|
|
71567
71644
|
cause: error
|
|
@@ -72326,10 +72403,10 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* (codexConfig, o
|
|
|
72326
72403
|
const runtimeEventQueue = yield* Queue.unbounded();
|
|
72327
72404
|
const sessions = /* @__PURE__ */ new Map();
|
|
72328
72405
|
const startSession = (input) => Effect.scoped(Effect.gen(function* () {
|
|
72329
|
-
if (input.provider !== void 0 && input.provider !== PROVIDER$
|
|
72330
|
-
provider: PROVIDER$
|
|
72406
|
+
if (input.provider !== void 0 && input.provider !== PROVIDER$4) return yield* new ProviderAdapterValidationError({
|
|
72407
|
+
provider: PROVIDER$4,
|
|
72331
72408
|
operation: "startSession",
|
|
72332
|
-
issue: `Expected provider '${PROVIDER$
|
|
72409
|
+
issue: `Expected provider '${PROVIDER$4}' but received '${input.provider}'.`
|
|
72333
72410
|
});
|
|
72334
72411
|
const existing = sessions.get(input.threadId);
|
|
72335
72412
|
if (existing && !existing.stopped) yield* Effect.suspend(() => stopSessionInternal(existing));
|
|
@@ -72364,7 +72441,7 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* (codexConfig, o
|
|
|
72364
72441
|
let sessionScopeTransferred = false;
|
|
72365
72442
|
yield* Effect.addFinalizer(() => sessionScopeTransferred ? Effect.void : Scope.close(sessionScope, Exit.void));
|
|
72366
72443
|
const runtime = yield* (options?.makeRuntime ?? makeCodexSessionRuntime)(runtimeInput).pipe(Effect.provideService(Scope.Scope, sessionScope), Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, childProcessSpawner), Effect.provideService(Crypto.Crypto, crypto), Effect.mapError((cause) => new ProviderAdapterProcessError({
|
|
72367
|
-
provider: PROVIDER$
|
|
72444
|
+
provider: PROVIDER$4,
|
|
72368
72445
|
threadId: input.threadId,
|
|
72369
72446
|
detail: cause.message,
|
|
72370
72447
|
cause
|
|
@@ -72384,7 +72461,7 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* (codexConfig, o
|
|
|
72384
72461
|
yield* Queue.offerAll(runtimeEventQueue, runtimeEvents);
|
|
72385
72462
|
})).pipe(Effect.forkChild);
|
|
72386
72463
|
const started = yield* runtime.start().pipe(Effect.mapError((cause) => new ProviderAdapterProcessError({
|
|
72387
|
-
provider: PROVIDER$
|
|
72464
|
+
provider: PROVIDER$4,
|
|
72388
72465
|
threadId: input.threadId,
|
|
72389
72466
|
detail: cause.message,
|
|
72390
72467
|
cause
|
|
@@ -72405,12 +72482,12 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* (codexConfig, o
|
|
|
72405
72482
|
attachment
|
|
72406
72483
|
});
|
|
72407
72484
|
if (!attachmentPath) return yield* new ProviderAdapterRequestError({
|
|
72408
|
-
provider: PROVIDER$
|
|
72485
|
+
provider: PROVIDER$4,
|
|
72409
72486
|
method: "turn/start",
|
|
72410
72487
|
detail: `Invalid attachment id '${attachment.id}'.`
|
|
72411
72488
|
});
|
|
72412
72489
|
const bytes = yield* fileSystem.readFile(attachmentPath).pipe(Effect.mapError((cause) => new ProviderAdapterRequestError({
|
|
72413
|
-
provider: PROVIDER$
|
|
72490
|
+
provider: PROVIDER$4,
|
|
72414
72491
|
method: "turn/start",
|
|
72415
72492
|
detail: `Failed to read attachment file: ${cause.message}.`,
|
|
72416
72493
|
cause
|
|
@@ -72438,7 +72515,7 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* (codexConfig, o
|
|
|
72438
72515
|
const requireSession = Effect.fn("requireSession")(function* (threadId) {
|
|
72439
72516
|
const session = sessions.get(threadId);
|
|
72440
72517
|
if (!session || session.stopped) return yield* new ProviderAdapterSessionNotFoundError({
|
|
72441
|
-
provider: PROVIDER$
|
|
72518
|
+
provider: PROVIDER$4,
|
|
72442
72519
|
threadId
|
|
72443
72520
|
});
|
|
72444
72521
|
return session;
|
|
@@ -72450,7 +72527,7 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* (codexConfig, o
|
|
|
72450
72527
|
})));
|
|
72451
72528
|
const rollbackThread = (threadId, numTurns) => {
|
|
72452
72529
|
if (!Number.isInteger(numTurns) || numTurns < 1) return Effect.fail(new ProviderAdapterValidationError({
|
|
72453
|
-
provider: PROVIDER$
|
|
72530
|
+
provider: PROVIDER$4,
|
|
72454
72531
|
operation: "rollbackThread",
|
|
72455
72532
|
issue: "numTurns must be an integer >= 1."
|
|
72456
72533
|
}));
|
|
@@ -72486,7 +72563,7 @@ const makeCodexAdapter = Effect.fn("makeCodexAdapter")(function* (codexConfig, o
|
|
|
72486
72563
|
}).pipe(Effect.asVoid);
|
|
72487
72564
|
yield* Effect.acquireRelease(Effect.void, () => stopAll().pipe(Effect.andThen(Queue.shutdown(runtimeEventQueue)), Effect.andThen(managedNativeEventLogger?.close() ?? Effect.void), Effect.ignore));
|
|
72488
72565
|
return {
|
|
72489
|
-
provider: PROVIDER$
|
|
72566
|
+
provider: PROVIDER$4,
|
|
72490
72567
|
capabilities: { sessionModelSwitch: "in-session" },
|
|
72491
72568
|
startSession,
|
|
72492
72569
|
sendTurn,
|
|
@@ -72781,8 +72858,8 @@ function codexContinuationIdentity(layout) {
|
|
|
72781
72858
|
* @module provider/Drivers/CodexDriver
|
|
72782
72859
|
*/
|
|
72783
72860
|
const decodeCodexSettings = Schema$1.decodeSync(CodexSettings);
|
|
72784
|
-
const DRIVER_KIND$
|
|
72785
|
-
const SNAPSHOT_REFRESH_INTERVAL$
|
|
72861
|
+
const DRIVER_KIND$4 = ProviderDriverKind.make("codex");
|
|
72862
|
+
const SNAPSHOT_REFRESH_INTERVAL$4 = Duration.minutes(5);
|
|
72786
72863
|
/**
|
|
72787
72864
|
* Codex's own installer puts a launcher in `~/.local/bin` pointing at a
|
|
72788
72865
|
* versioned release under `~/.codex/packages/standalone/`. That layout matches
|
|
@@ -72795,8 +72872,8 @@ function isCodexNativeCommandPath(commandPath) {
|
|
|
72795
72872
|
const normalized = normalizeCommandPath(commandPath);
|
|
72796
72873
|
return normalized.endsWith("/.local/bin/codex") || normalized.endsWith("/.local/bin/codex.exe") || normalized.includes("/.codex/packages/standalone/");
|
|
72797
72874
|
}
|
|
72798
|
-
const UPDATE$
|
|
72799
|
-
provider: DRIVER_KIND$
|
|
72875
|
+
const UPDATE$4 = makePackageManagedProviderMaintenanceResolver({
|
|
72876
|
+
provider: DRIVER_KIND$4,
|
|
72800
72877
|
npmPackageName: "@openai/codex",
|
|
72801
72878
|
homebrewFormula: "codex",
|
|
72802
72879
|
nativeUpdate: {
|
|
@@ -72812,16 +72889,16 @@ const UPDATE$3 = makePackageManagedProviderMaintenanceResolver({
|
|
|
72812
72889
|
* `providerSnapshot.ts` is widened to accept `instanceId`/`driver`, this
|
|
72813
72890
|
* wrapper disappears.
|
|
72814
72891
|
*/
|
|
72815
|
-
const withInstanceIdentity$
|
|
72892
|
+
const withInstanceIdentity$4 = (input) => (snapshot) => ({
|
|
72816
72893
|
...snapshot,
|
|
72817
72894
|
instanceId: input.instanceId,
|
|
72818
|
-
driver: DRIVER_KIND$
|
|
72895
|
+
driver: DRIVER_KIND$4,
|
|
72819
72896
|
...input.displayName ? { displayName: input.displayName } : {},
|
|
72820
72897
|
...input.accentColor ? { accentColor: input.accentColor } : {},
|
|
72821
72898
|
continuation: { groupKey: input.continuationGroupKey }
|
|
72822
72899
|
});
|
|
72823
72900
|
const CodexDriver = {
|
|
72824
|
-
driverKind: DRIVER_KIND$
|
|
72901
|
+
driverKind: DRIVER_KIND$4,
|
|
72825
72902
|
metadata: {
|
|
72826
72903
|
displayName: "Codex",
|
|
72827
72904
|
supportsMultipleInstances: true
|
|
@@ -72836,14 +72913,14 @@ const CodexDriver = {
|
|
|
72836
72913
|
const processEnv = mergeProviderInstanceEnvironment(environment);
|
|
72837
72914
|
const homeLayout = yield* resolveCodexHomeLayout(config);
|
|
72838
72915
|
const continuationIdentity = codexContinuationIdentity(homeLayout);
|
|
72839
|
-
const stampIdentity = withInstanceIdentity$
|
|
72916
|
+
const stampIdentity = withInstanceIdentity$4({
|
|
72840
72917
|
instanceId,
|
|
72841
72918
|
displayName,
|
|
72842
72919
|
accentColor,
|
|
72843
72920
|
continuationGroupKey: continuationIdentity.continuationKey
|
|
72844
72921
|
});
|
|
72845
72922
|
yield* materializeCodexShadowHome(homeLayout).pipe(Effect.mapError((cause) => new ProviderDriverError({
|
|
72846
|
-
driver: DRIVER_KIND$
|
|
72923
|
+
driver: DRIVER_KIND$4,
|
|
72847
72924
|
instanceId,
|
|
72848
72925
|
detail: cause.message,
|
|
72849
72926
|
cause
|
|
@@ -72853,7 +72930,7 @@ const CodexDriver = {
|
|
|
72853
72930
|
enabled,
|
|
72854
72931
|
homePath: homeLayout.effectiveHomePath ?? ""
|
|
72855
72932
|
};
|
|
72856
|
-
const maintenanceCapabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(UPDATE$
|
|
72933
|
+
const maintenanceCapabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(UPDATE$4, {
|
|
72857
72934
|
binaryPath: effectiveConfig.binaryPath,
|
|
72858
72935
|
env: processEnv
|
|
72859
72936
|
});
|
|
@@ -72873,16 +72950,16 @@ const CodexDriver = {
|
|
|
72873
72950
|
initialSnapshot: (settings) => makePendingCodexProvider(settings.provider).pipe(Effect.map(stampIdentity)),
|
|
72874
72951
|
checkProvider,
|
|
72875
72952
|
enrichSnapshot: ({ settings, snapshot, publishSnapshot }) => enrichProviderSnapshotWithVersionAdvisory(snapshot, maintenanceCapabilities, { enableProviderUpdateChecks: settings.enableProviderUpdateChecks }).pipe(Effect.provideService(HttpClient.HttpClient, httpClient), Effect.flatMap((enrichedSnapshot) => publishSnapshot(enrichedSnapshot))),
|
|
72876
|
-
refreshInterval: SNAPSHOT_REFRESH_INTERVAL$
|
|
72953
|
+
refreshInterval: SNAPSHOT_REFRESH_INTERVAL$4
|
|
72877
72954
|
}).pipe(Effect.mapError((cause) => new ProviderDriverError({
|
|
72878
|
-
driver: DRIVER_KIND$
|
|
72955
|
+
driver: DRIVER_KIND$4,
|
|
72879
72956
|
instanceId,
|
|
72880
72957
|
detail: `Failed to build Codex snapshot: ${cause.message ?? String(cause)}`,
|
|
72881
72958
|
cause
|
|
72882
72959
|
})));
|
|
72883
72960
|
return {
|
|
72884
72961
|
instanceId,
|
|
72885
|
-
driverKind: DRIVER_KIND$
|
|
72962
|
+
driverKind: DRIVER_KIND$4,
|
|
72886
72963
|
continuationIdentity,
|
|
72887
72964
|
displayName,
|
|
72888
72965
|
accentColor,
|
|
@@ -76859,18 +76936,18 @@ function deriveToolActivityPresentation(input) {
|
|
|
76859
76936
|
}
|
|
76860
76937
|
//#endregion
|
|
76861
76938
|
//#region src/provider/acp/AcpRuntimeModel.ts
|
|
76862
|
-
function isRecord$
|
|
76939
|
+
function isRecord$4(value) {
|
|
76863
76940
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
76864
76941
|
}
|
|
76865
76942
|
function isSessionModelState(value) {
|
|
76866
|
-
if (!isRecord$
|
|
76943
|
+
if (!isRecord$4(value) || typeof value.currentModelId !== "string") return false;
|
|
76867
76944
|
if (!Array.isArray(value.availableModels)) return false;
|
|
76868
|
-
return value.availableModels.every((model) => isRecord$
|
|
76945
|
+
return value.availableModels.every((model) => isRecord$4(model) && typeof model.modelId === "string" && typeof model.name === "string" && (model.description === void 0 || model.description === null || typeof model.description === "string"));
|
|
76869
76946
|
}
|
|
76870
76947
|
function isSessionModeState(value) {
|
|
76871
|
-
if (!isRecord$
|
|
76948
|
+
if (!isRecord$4(value) || typeof value.currentModeId !== "string") return false;
|
|
76872
76949
|
if (!Array.isArray(value.availableModes)) return false;
|
|
76873
|
-
return value.availableModes.every((mode) => isRecord$
|
|
76950
|
+
return value.availableModes.every((mode) => isRecord$4(mode) && typeof mode.id === "string" && typeof mode.name === "string" && (mode.description === void 0 || typeof mode.description === "string"));
|
|
76874
76951
|
}
|
|
76875
76952
|
function extractModelConfigId(sessionResponse) {
|
|
76876
76953
|
const configOptions = sessionResponse.configOptions;
|
|
@@ -76946,7 +77023,7 @@ function extractCommandFromTitle(title) {
|
|
|
76946
77023
|
return /`([^`]+)`/.exec(title)?.[1]?.trim() || void 0;
|
|
76947
77024
|
}
|
|
76948
77025
|
function extractToolCallCommand(rawInput, title) {
|
|
76949
|
-
if (isRecord$
|
|
77026
|
+
if (isRecord$4(rawInput)) {
|
|
76950
77027
|
const directCommand = normalizeCommandValue(rawInput.command);
|
|
76951
77028
|
if (directCommand) return directCommand;
|
|
76952
77029
|
const executable = typeof rawInput.executable === "string" ? rawInput.executable.trim() : "";
|
|
@@ -77068,7 +77145,7 @@ function parsePermissionRequest(params) {
|
|
|
77068
77145
|
}
|
|
77069
77146
|
function sessionUpdateIsReplay(params) {
|
|
77070
77147
|
const meta = params._meta;
|
|
77071
|
-
return isRecord$
|
|
77148
|
+
return isRecord$4(meta) && meta.isReplay === true;
|
|
77072
77149
|
}
|
|
77073
77150
|
const waitForSessionLoadReplayIdle = (input) => Effect.gen(function* () {
|
|
77074
77151
|
const pollInterval = Duration.millis(25);
|
|
@@ -77083,8 +77160,8 @@ const waitForSessionLoadReplayIdle = (input) => Effect.gen(function* () {
|
|
|
77083
77160
|
});
|
|
77084
77161
|
function syntheticLoadSessionResponseFromInitialize(initializeResult) {
|
|
77085
77162
|
const meta = initializeResult._meta;
|
|
77086
|
-
const modelState = isRecord$
|
|
77087
|
-
const modeState = isRecord$
|
|
77163
|
+
const modelState = isRecord$4(meta) ? meta.modelState : void 0;
|
|
77164
|
+
const modeState = isRecord$4(meta) ? meta.modeState : void 0;
|
|
77088
77165
|
const models = isSessionModelState(modelState) ? modelState : void 0;
|
|
77089
77166
|
const modes = isSessionModeState(modeState) ? modeState : void 0;
|
|
77090
77167
|
return {
|
|
@@ -77642,7 +77719,7 @@ const CURSOR_PRESENTATION = {
|
|
|
77642
77719
|
badgeLabel: "Early Access",
|
|
77643
77720
|
showInteractionModeToggle: true
|
|
77644
77721
|
};
|
|
77645
|
-
const EMPTY_CAPABILITIES$
|
|
77722
|
+
const EMPTY_CAPABILITIES$2 = createModelCapabilities({ optionDescriptors: [] });
|
|
77646
77723
|
const CURSOR_ACP_MODEL_DISCOVERY_TIMEOUT_MS = 15e3;
|
|
77647
77724
|
const CURSOR_PARAMETERIZED_MODEL_PICKER_MIN_VERSION_DATE = 20260408;
|
|
77648
77725
|
const CURSOR_CLI_INSTALLATION_DOCS_URL = "https://cursor.com/docs/cli/installation";
|
|
@@ -77750,7 +77827,7 @@ function getBooleanCurrentValue(option) {
|
|
|
77750
77827
|
if (normalized === "false") return false;
|
|
77751
77828
|
}
|
|
77752
77829
|
function buildCursorCapabilitiesFromConfigOptions(configOptions) {
|
|
77753
|
-
if (!configOptions || configOptions.length === 0) return EMPTY_CAPABILITIES$
|
|
77830
|
+
if (!configOptions || configOptions.length === 0) return EMPTY_CAPABILITIES$2;
|
|
77754
77831
|
const reasoningConfig = findCursorEffortConfigOption(configOptions);
|
|
77755
77832
|
const reasoningEffortLevels = reasoningConfig?.type === "select" ? flattenSessionConfigSelectOptions(reasoningConfig).flatMap((entry) => {
|
|
77756
77833
|
const normalizedValue = normalizeCursorReasoningValue(entry.value);
|
|
@@ -77919,7 +77996,7 @@ const discoverCursorModelsViaListAvailableModels = (cursorSettings, environment)
|
|
|
77919
77996
|
}), environment);
|
|
77920
77997
|
const discoverCursorModelsViaAcp = (cursorSettings, environment) => discoverCursorModelsViaListAvailableModels(cursorSettings, environment);
|
|
77921
77998
|
function getCursorFallbackModels(cursorSettings) {
|
|
77922
|
-
return providerModelsFromSettings([], cursorSettings.customModels, EMPTY_CAPABILITIES$
|
|
77999
|
+
return providerModelsFromSettings([], cursorSettings.customModels, EMPTY_CAPABILITIES$2);
|
|
77923
78000
|
}
|
|
77924
78001
|
/** Timeout for `agent about` — it's slower than a simple `--version` probe. */
|
|
77925
78002
|
const ABOUT_TIMEOUT_MS = 8e3;
|
|
@@ -77955,7 +78032,7 @@ function buildCursorProviderSnapshot(input) {
|
|
|
77955
78032
|
presentation: CURSOR_PRESENTATION,
|
|
77956
78033
|
enabled: input.cursorSettings.enabled,
|
|
77957
78034
|
checkedAt: input.checkedAt,
|
|
77958
|
-
models: providerModelsFromSettings(input.discoveredModels ?? [], input.cursorSettings.customModels, EMPTY_CAPABILITIES$
|
|
78035
|
+
models: providerModelsFromSettings(input.discoveredModels ?? [], input.cursorSettings.customModels, EMPTY_CAPABILITIES$2),
|
|
77959
78036
|
probe: {
|
|
77960
78037
|
installed: true,
|
|
77961
78038
|
version: input.parsed.version,
|
|
@@ -78308,7 +78385,7 @@ function applyCursorAcpModelSelection(input) {
|
|
|
78308
78385
|
//#endregion
|
|
78309
78386
|
//#region src/textGeneration/CursorTextGeneration.ts
|
|
78310
78387
|
const CURSOR_TIMEOUT_MS = 18e4;
|
|
78311
|
-
const isTextGenerationError$
|
|
78388
|
+
const isTextGenerationError$2 = Schema$1.is(TextGenerationError);
|
|
78312
78389
|
/**
|
|
78313
78390
|
* Build a Cursor text-generation closure bound to a specific `CursorSettings`
|
|
78314
78391
|
* payload. See `makeCodexAdapter` for the overall per-instance rationale.
|
|
@@ -78359,7 +78436,7 @@ const makeCursorTextGeneration = Effect.fn("makeCursorTextGeneration")(function*
|
|
|
78359
78436
|
detail: "Cursor Agent request timed out."
|
|
78360
78437
|
})),
|
|
78361
78438
|
onSome: (value) => Effect.succeed(value)
|
|
78362
|
-
})), Effect.mapError((cause) => isTextGenerationError$
|
|
78439
|
+
})), Effect.mapError((cause) => isTextGenerationError$2(cause) ? cause : new TextGenerationError({
|
|
78363
78440
|
operation,
|
|
78364
78441
|
detail: "Cursor ACP request failed.",
|
|
78365
78442
|
cause
|
|
@@ -78374,7 +78451,7 @@ const makeCursorTextGeneration = Effect.fn("makeCursorTextGeneration")(function*
|
|
|
78374
78451
|
detail: "Cursor Agent returned invalid structured output.",
|
|
78375
78452
|
cause
|
|
78376
78453
|
})) }));
|
|
78377
|
-
}).pipe(Effect.mapError((cause) => isTextGenerationError$
|
|
78454
|
+
}).pipe(Effect.mapError((cause) => isTextGenerationError$2(cause) ? cause : new TextGenerationError({
|
|
78378
78455
|
operation,
|
|
78379
78456
|
detail: "Cursor ACP text generation failed.",
|
|
78380
78457
|
cause
|
|
@@ -78716,7 +78793,7 @@ const makeAcpNativeLoggerFactory = Effect.fn("makeAcpNativeLoggerFactory")(funct
|
|
|
78716
78793
|
* @module CursorAdapterLive
|
|
78717
78794
|
*/
|
|
78718
78795
|
const encodeUnknownJsonStringExit$1 = Schema$1.encodeUnknownExit(Schema$1.UnknownFromJsonString);
|
|
78719
|
-
const PROVIDER$
|
|
78796
|
+
const PROVIDER$3 = ProviderDriverKind.make("cursor");
|
|
78720
78797
|
const CURSOR_RESUME_VERSION = 1;
|
|
78721
78798
|
const ACP_PLAN_MODE_ALIASES = ["plan", "architect"];
|
|
78722
78799
|
const ACP_IMPLEMENT_MODE_ALIASES = [
|
|
@@ -78739,11 +78816,11 @@ function settlePendingUserInputsAsEmptyAnswers(pendingUserInputs) {
|
|
|
78739
78816
|
const pendingEntries = Array.from(pendingUserInputs.values());
|
|
78740
78817
|
return Effect.forEach(pendingEntries, (pending) => Deferred.succeed(pending.answers, {}).pipe(Effect.ignore), { discard: true });
|
|
78741
78818
|
}
|
|
78742
|
-
function isRecord$
|
|
78819
|
+
function isRecord$3(value) {
|
|
78743
78820
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
78744
78821
|
}
|
|
78745
78822
|
function parseCursorResume(raw) {
|
|
78746
|
-
if (!isRecord$
|
|
78823
|
+
if (!isRecord$3(raw)) return void 0;
|
|
78747
78824
|
if (raw.schemaVersion !== CURSOR_RESUME_VERSION) return void 0;
|
|
78748
78825
|
if (typeof raw.sessionId !== "string" || !raw.sessionId.trim()) return void 0;
|
|
78749
78826
|
return { sessionId: raw.sessionId.trim() };
|
|
@@ -78825,7 +78902,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
78825
78902
|
const runtimeEventPubSub = yield* PubSub.unbounded();
|
|
78826
78903
|
const nowIso = Effect.map(DateTime.now, DateTime.formatIso);
|
|
78827
78904
|
const randomUUIDv4 = crypto.randomUUIDv4.pipe(Effect.mapError((cause) => new ProviderAdapterRequestError({
|
|
78828
|
-
provider: PROVIDER$
|
|
78905
|
+
provider: PROVIDER$3,
|
|
78829
78906
|
method: "crypto/randomUUIDv4",
|
|
78830
78907
|
detail: "Failed to generate Cursor runtime identifier.",
|
|
78831
78908
|
cause
|
|
@@ -78860,7 +78937,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
78860
78937
|
event: {
|
|
78861
78938
|
id: yield* randomUUIDv4,
|
|
78862
78939
|
kind: "notification",
|
|
78863
|
-
provider: PROVIDER$
|
|
78940
|
+
provider: PROVIDER$3,
|
|
78864
78941
|
createdAt: observedAt,
|
|
78865
78942
|
method,
|
|
78866
78943
|
threadId,
|
|
@@ -78874,7 +78951,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
78874
78951
|
ctx.lastPlanFingerprint = fingerprint;
|
|
78875
78952
|
yield* offerRuntimeEvent(makeAcpPlanUpdatedEvent({
|
|
78876
78953
|
stamp: yield* makeEventStamp(),
|
|
78877
|
-
provider: PROVIDER$
|
|
78954
|
+
provider: PROVIDER$3,
|
|
78878
78955
|
threadId: ctx.threadId,
|
|
78879
78956
|
turnId: ctx.activeTurnId,
|
|
78880
78957
|
payload,
|
|
@@ -78886,7 +78963,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
78886
78963
|
const requireSession = (threadId) => {
|
|
78887
78964
|
const ctx = sessions.get(threadId);
|
|
78888
78965
|
if (!ctx || ctx.stopped) return Effect.fail(new ProviderAdapterSessionNotFoundError({
|
|
78889
|
-
provider: PROVIDER$
|
|
78966
|
+
provider: PROVIDER$3,
|
|
78890
78967
|
threadId
|
|
78891
78968
|
}));
|
|
78892
78969
|
return Effect.succeed(ctx);
|
|
@@ -78902,19 +78979,19 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
78902
78979
|
yield* offerRuntimeEvent({
|
|
78903
78980
|
type: "session.exited",
|
|
78904
78981
|
...yield* makeEventStamp(),
|
|
78905
|
-
provider: PROVIDER$
|
|
78982
|
+
provider: PROVIDER$3,
|
|
78906
78983
|
threadId: ctx.threadId,
|
|
78907
78984
|
payload: { exitKind: "graceful" }
|
|
78908
78985
|
});
|
|
78909
78986
|
});
|
|
78910
78987
|
const startSession = (input) => withThreadLock(input.threadId, Effect.gen(function* () {
|
|
78911
|
-
if (input.provider !== void 0 && input.provider !== PROVIDER$
|
|
78912
|
-
provider: PROVIDER$
|
|
78988
|
+
if (input.provider !== void 0 && input.provider !== PROVIDER$3) return yield* new ProviderAdapterValidationError({
|
|
78989
|
+
provider: PROVIDER$3,
|
|
78913
78990
|
operation: "startSession",
|
|
78914
|
-
issue: `Expected provider '${PROVIDER$
|
|
78991
|
+
issue: `Expected provider '${PROVIDER$3}' but received '${input.provider}'.`
|
|
78915
78992
|
});
|
|
78916
78993
|
if (!input.cwd?.trim()) return yield* new ProviderAdapterValidationError({
|
|
78917
|
-
provider: PROVIDER$
|
|
78994
|
+
provider: PROVIDER$3,
|
|
78918
78995
|
operation: "startSession",
|
|
78919
78996
|
issue: "cwd is required and must be non-empty."
|
|
78920
78997
|
});
|
|
@@ -78931,7 +79008,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
78931
79008
|
const resumeSessionId = parseCursorResume(input.resumeCursor)?.sessionId;
|
|
78932
79009
|
const acpNativeLoggers = makeAcpNativeLoggers({
|
|
78933
79010
|
nativeEventLogger,
|
|
78934
|
-
provider: PROVIDER$
|
|
79011
|
+
provider: PROVIDER$3,
|
|
78935
79012
|
threadId: input.threadId
|
|
78936
79013
|
});
|
|
78937
79014
|
const effectiveCursorSettings = options?.resolveSettings ? yield* options.resolveSettings : cursorSettings;
|
|
@@ -78957,7 +79034,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
78957
79034
|
}] } : {},
|
|
78958
79035
|
...acpNativeLoggers
|
|
78959
79036
|
}).pipe(Effect.provideService(Crypto.Crypto, crypto), Effect.provideService(Scope.Scope, sessionScope), Effect.mapError((cause) => new ProviderAdapterProcessError({
|
|
78960
|
-
provider: PROVIDER$
|
|
79037
|
+
provider: PROVIDER$3,
|
|
78961
79038
|
threadId: input.threadId,
|
|
78962
79039
|
detail: cause.message,
|
|
78963
79040
|
cause
|
|
@@ -78972,7 +79049,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
78972
79049
|
yield* offerRuntimeEvent({
|
|
78973
79050
|
type: "user-input.requested",
|
|
78974
79051
|
...yield* makeEventStamp(),
|
|
78975
|
-
provider: PROVIDER$
|
|
79052
|
+
provider: PROVIDER$3,
|
|
78976
79053
|
threadId: input.threadId,
|
|
78977
79054
|
turnId: ctx?.activeTurnId,
|
|
78978
79055
|
requestId: runtimeRequestId,
|
|
@@ -78988,7 +79065,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
78988
79065
|
yield* offerRuntimeEvent({
|
|
78989
79066
|
type: "user-input.resolved",
|
|
78990
79067
|
...yield* makeEventStamp(),
|
|
78991
|
-
provider: PROVIDER$
|
|
79068
|
+
provider: PROVIDER$3,
|
|
78992
79069
|
threadId: input.threadId,
|
|
78993
79070
|
turnId: ctx?.activeTurnId,
|
|
78994
79071
|
requestId: runtimeRequestId,
|
|
@@ -79001,7 +79078,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79001
79078
|
yield* offerRuntimeEvent({
|
|
79002
79079
|
type: "turn.proposed.completed",
|
|
79003
79080
|
...yield* makeEventStamp(),
|
|
79004
|
-
provider: PROVIDER$
|
|
79081
|
+
provider: PROVIDER$3,
|
|
79005
79082
|
threadId: input.threadId,
|
|
79006
79083
|
turnId: ctx?.activeTurnId,
|
|
79007
79084
|
payload: { planMarkdown: extractPlanMarkdown(params) },
|
|
@@ -79036,7 +79113,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79036
79113
|
});
|
|
79037
79114
|
yield* offerRuntimeEvent(makeAcpRequestOpenedEvent({
|
|
79038
79115
|
stamp: yield* makeEventStamp(),
|
|
79039
|
-
provider: PROVIDER$
|
|
79116
|
+
provider: PROVIDER$3,
|
|
79040
79117
|
threadId: input.threadId,
|
|
79041
79118
|
turnId: ctx?.activeTurnId,
|
|
79042
79119
|
requestId: runtimeRequestId,
|
|
@@ -79051,7 +79128,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79051
79128
|
pendingApprovals.delete(requestId);
|
|
79052
79129
|
yield* offerRuntimeEvent(makeAcpRequestResolvedEvent({
|
|
79053
79130
|
stamp: yield* makeEventStamp(),
|
|
79054
|
-
provider: PROVIDER$
|
|
79131
|
+
provider: PROVIDER$3,
|
|
79055
79132
|
threadId: input.threadId,
|
|
79056
79133
|
turnId: ctx?.activeTurnId,
|
|
79057
79134
|
requestId: runtimeRequestId,
|
|
@@ -79064,17 +79141,17 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79064
79141
|
} };
|
|
79065
79142
|
})));
|
|
79066
79143
|
return yield* acp.start();
|
|
79067
|
-
}).pipe(Effect.mapError((error) => mapAcpToAdapterError(PROVIDER$
|
|
79144
|
+
}).pipe(Effect.mapError((error) => mapAcpToAdapterError(PROVIDER$3, input.threadId, "session/start", error)));
|
|
79068
79145
|
yield* applyRequestedSessionConfiguration({
|
|
79069
79146
|
runtime: acp,
|
|
79070
79147
|
runtimeMode: input.runtimeMode,
|
|
79071
79148
|
interactionMode: void 0,
|
|
79072
79149
|
modelSelection: cursorModelSelection,
|
|
79073
|
-
mapError: ({ cause, method }) => mapAcpToAdapterError(PROVIDER$
|
|
79150
|
+
mapError: ({ cause, method }) => mapAcpToAdapterError(PROVIDER$3, input.threadId, method, cause)
|
|
79074
79151
|
});
|
|
79075
79152
|
const now = yield* nowIso;
|
|
79076
79153
|
const session = {
|
|
79077
|
-
provider: PROVIDER$
|
|
79154
|
+
provider: PROVIDER$3,
|
|
79078
79155
|
providerInstanceId: boundInstanceId,
|
|
79079
79156
|
status: "ready",
|
|
79080
79157
|
runtimeMode: input.runtimeMode,
|
|
@@ -79111,7 +79188,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79111
79188
|
case "AssistantItemStarted":
|
|
79112
79189
|
yield* offerRuntimeEvent(makeAcpAssistantItemEvent({
|
|
79113
79190
|
stamp: yield* makeEventStamp(),
|
|
79114
|
-
provider: PROVIDER$
|
|
79191
|
+
provider: PROVIDER$3,
|
|
79115
79192
|
threadId: ctx.threadId,
|
|
79116
79193
|
turnId: ctx.activeTurnId,
|
|
79117
79194
|
itemId: event.itemId,
|
|
@@ -79121,7 +79198,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79121
79198
|
case "AssistantItemCompleted":
|
|
79122
79199
|
yield* offerRuntimeEvent(makeAcpAssistantItemEvent({
|
|
79123
79200
|
stamp: yield* makeEventStamp(),
|
|
79124
|
-
provider: PROVIDER$
|
|
79201
|
+
provider: PROVIDER$3,
|
|
79125
79202
|
threadId: ctx.threadId,
|
|
79126
79203
|
turnId: ctx.activeTurnId,
|
|
79127
79204
|
itemId: event.itemId,
|
|
@@ -79136,7 +79213,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79136
79213
|
yield* logNative(ctx.threadId, "session/update", event.rawPayload, "acp.jsonrpc");
|
|
79137
79214
|
yield* offerRuntimeEvent(makeAcpToolCallEvent({
|
|
79138
79215
|
stamp: yield* makeEventStamp(),
|
|
79139
|
-
provider: PROVIDER$
|
|
79216
|
+
provider: PROVIDER$3,
|
|
79140
79217
|
threadId: ctx.threadId,
|
|
79141
79218
|
turnId: ctx.activeTurnId,
|
|
79142
79219
|
toolCall: event.toolCall,
|
|
@@ -79147,7 +79224,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79147
79224
|
yield* logNative(ctx.threadId, "session/update", event.rawPayload, "acp.jsonrpc");
|
|
79148
79225
|
yield* offerRuntimeEvent(makeAcpContentDeltaEvent({
|
|
79149
79226
|
stamp: yield* makeEventStamp(),
|
|
79150
|
-
provider: PROVIDER$
|
|
79227
|
+
provider: PROVIDER$3,
|
|
79151
79228
|
threadId: ctx.threadId,
|
|
79152
79229
|
turnId: ctx.activeTurnId,
|
|
79153
79230
|
...event.itemId ? { itemId: event.itemId } : {},
|
|
@@ -79163,14 +79240,14 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79163
79240
|
yield* offerRuntimeEvent({
|
|
79164
79241
|
type: "session.started",
|
|
79165
79242
|
...yield* makeEventStamp(),
|
|
79166
|
-
provider: PROVIDER$
|
|
79243
|
+
provider: PROVIDER$3,
|
|
79167
79244
|
threadId: input.threadId,
|
|
79168
79245
|
payload: { resume: started.initializeResult }
|
|
79169
79246
|
});
|
|
79170
79247
|
yield* offerRuntimeEvent({
|
|
79171
79248
|
type: "session.state.changed",
|
|
79172
79249
|
...yield* makeEventStamp(),
|
|
79173
|
-
provider: PROVIDER$
|
|
79250
|
+
provider: PROVIDER$3,
|
|
79174
79251
|
threadId: input.threadId,
|
|
79175
79252
|
payload: {
|
|
79176
79253
|
state: "ready",
|
|
@@ -79180,7 +79257,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79180
79257
|
yield* offerRuntimeEvent({
|
|
79181
79258
|
type: "thread.started",
|
|
79182
79259
|
...yield* makeEventStamp(),
|
|
79183
|
-
provider: PROVIDER$
|
|
79260
|
+
provider: PROVIDER$3,
|
|
79184
79261
|
threadId: input.threadId,
|
|
79185
79262
|
payload: { providerThreadId: started.sessionId }
|
|
79186
79263
|
});
|
|
@@ -79203,7 +79280,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79203
79280
|
model,
|
|
79204
79281
|
options: turnModelSelection?.options
|
|
79205
79282
|
},
|
|
79206
|
-
mapError: ({ cause, method }) => mapAcpToAdapterError(PROVIDER$
|
|
79283
|
+
mapError: ({ cause, method }) => mapAcpToAdapterError(PROVIDER$3, input.threadId, method, cause)
|
|
79207
79284
|
});
|
|
79208
79285
|
ctx.activeTurnId = turnId;
|
|
79209
79286
|
if (steeringTurnId === void 0) ctx.lastPlanFingerprint = void 0;
|
|
@@ -79215,7 +79292,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79215
79292
|
if (steeringTurnId === void 0) yield* offerRuntimeEvent({
|
|
79216
79293
|
type: "turn.started",
|
|
79217
79294
|
...yield* makeEventStamp(),
|
|
79218
|
-
provider: PROVIDER$
|
|
79295
|
+
provider: PROVIDER$3,
|
|
79219
79296
|
threadId: input.threadId,
|
|
79220
79297
|
turnId,
|
|
79221
79298
|
payload: { model: resolvedModel }
|
|
@@ -79231,12 +79308,12 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79231
79308
|
attachment
|
|
79232
79309
|
});
|
|
79233
79310
|
if (!attachmentPath) return yield* new ProviderAdapterRequestError({
|
|
79234
|
-
provider: PROVIDER$
|
|
79311
|
+
provider: PROVIDER$3,
|
|
79235
79312
|
method: "session/prompt",
|
|
79236
79313
|
detail: `Invalid attachment id '${attachment.id}'.`
|
|
79237
79314
|
});
|
|
79238
79315
|
const bytes = yield* fileSystem.readFile(attachmentPath).pipe(Effect.mapError((cause) => new ProviderAdapterRequestError({
|
|
79239
|
-
provider: PROVIDER$
|
|
79316
|
+
provider: PROVIDER$3,
|
|
79240
79317
|
method: "session/prompt",
|
|
79241
79318
|
detail: cause.message,
|
|
79242
79319
|
cause
|
|
@@ -79248,11 +79325,11 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79248
79325
|
});
|
|
79249
79326
|
}
|
|
79250
79327
|
if (promptParts.length === 0) return yield* new ProviderAdapterValidationError({
|
|
79251
|
-
provider: PROVIDER$
|
|
79328
|
+
provider: PROVIDER$3,
|
|
79252
79329
|
operation: "sendTurn",
|
|
79253
79330
|
issue: "Turn requires non-empty text or attachments."
|
|
79254
79331
|
});
|
|
79255
|
-
const result = yield* ctx.acp.prompt({ prompt: promptParts }).pipe(Effect.mapError((error) => mapAcpToAdapterError(PROVIDER$
|
|
79332
|
+
const result = yield* ctx.acp.prompt({ prompt: promptParts }).pipe(Effect.mapError((error) => mapAcpToAdapterError(PROVIDER$3, input.threadId, "session/prompt", error)));
|
|
79256
79333
|
const turnRecord = ctx.turns.find((turn) => turn.id === turnId);
|
|
79257
79334
|
if (turnRecord) turnRecord.items.push({
|
|
79258
79335
|
prompt: promptParts,
|
|
@@ -79274,7 +79351,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79274
79351
|
if (ctx.promptsInFlight === 1) yield* offerRuntimeEvent({
|
|
79275
79352
|
type: "turn.completed",
|
|
79276
79353
|
...yield* makeEventStamp(),
|
|
79277
|
-
provider: PROVIDER$
|
|
79354
|
+
provider: PROVIDER$3,
|
|
79278
79355
|
threadId: input.threadId,
|
|
79279
79356
|
turnId,
|
|
79280
79357
|
payload: {
|
|
@@ -79295,12 +79372,12 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79295
79372
|
const ctx = yield* requireSession(threadId);
|
|
79296
79373
|
yield* settlePendingApprovalsAsCancelled$1(ctx.pendingApprovals);
|
|
79297
79374
|
yield* settlePendingUserInputsAsEmptyAnswers(ctx.pendingUserInputs);
|
|
79298
|
-
yield* Effect.ignore(ctx.acp.cancel.pipe(Effect.mapError((error) => mapAcpToAdapterError(PROVIDER$
|
|
79375
|
+
yield* Effect.ignore(ctx.acp.cancel.pipe(Effect.mapError((error) => mapAcpToAdapterError(PROVIDER$3, threadId, "session/cancel", error))));
|
|
79299
79376
|
});
|
|
79300
79377
|
const respondToRequest = (threadId, requestId, decision) => Effect.gen(function* () {
|
|
79301
79378
|
const pending = (yield* requireSession(threadId)).pendingApprovals.get(requestId);
|
|
79302
79379
|
if (!pending) return yield* new ProviderAdapterRequestError({
|
|
79303
|
-
provider: PROVIDER$
|
|
79380
|
+
provider: PROVIDER$3,
|
|
79304
79381
|
method: "session/request_permission",
|
|
79305
79382
|
detail: `Unknown pending approval request: ${requestId}`
|
|
79306
79383
|
});
|
|
@@ -79309,7 +79386,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79309
79386
|
const respondToUserInput = (threadId, requestId, answers) => Effect.gen(function* () {
|
|
79310
79387
|
const pending = (yield* requireSession(threadId)).pendingUserInputs.get(requestId);
|
|
79311
79388
|
if (!pending) return yield* new ProviderAdapterRequestError({
|
|
79312
|
-
provider: PROVIDER$
|
|
79389
|
+
provider: PROVIDER$3,
|
|
79313
79390
|
method: "cursor/ask_question",
|
|
79314
79391
|
detail: `Unknown pending user-input request: ${requestId}`
|
|
79315
79392
|
});
|
|
@@ -79324,7 +79401,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79324
79401
|
const rollbackThread = (threadId, numTurns) => Effect.gen(function* () {
|
|
79325
79402
|
const ctx = yield* requireSession(threadId);
|
|
79326
79403
|
if (!Number.isInteger(numTurns) || numTurns < 1) return yield* new ProviderAdapterValidationError({
|
|
79327
|
-
provider: PROVIDER$
|
|
79404
|
+
provider: PROVIDER$3,
|
|
79328
79405
|
operation: "rollbackThread",
|
|
79329
79406
|
issue: "numTurns must be an integer >= 1."
|
|
79330
79407
|
});
|
|
@@ -79348,7 +79425,7 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79348
79425
|
yield* Effect.addFinalizer(() => Effect.forEach(sessions.values(), stopSessionInternal, { discard: true }).pipe(Effect.catch((cause) => Effect.logError("Failed to emit Cursor session shutdown event.", { cause })), Effect.tap(() => PubSub.shutdown(runtimeEventPubSub)), Effect.tap(() => managedNativeEventLogger?.close() ?? Effect.void)));
|
|
79349
79426
|
const streamEvents = Stream.fromPubSub(runtimeEventPubSub);
|
|
79350
79427
|
return {
|
|
79351
|
-
provider: PROVIDER$
|
|
79428
|
+
provider: PROVIDER$3,
|
|
79352
79429
|
capabilities: { sessionModelSwitch: "in-session" },
|
|
79353
79430
|
startSession,
|
|
79354
79431
|
sendTurn,
|
|
@@ -79381,25 +79458,25 @@ function makeCursorAdapter(cursorSettings, options) {
|
|
|
79381
79458
|
* @module provider/Drivers/CursorDriver
|
|
79382
79459
|
*/
|
|
79383
79460
|
const decodeCursorSettings = Schema$1.decodeSync(CursorSettings);
|
|
79384
|
-
const DRIVER_KIND$
|
|
79385
|
-
const SNAPSHOT_REFRESH_INTERVAL$
|
|
79386
|
-
const UPDATE$
|
|
79387
|
-
provider: DRIVER_KIND$
|
|
79461
|
+
const DRIVER_KIND$3 = ProviderDriverKind.make("cursor");
|
|
79462
|
+
const SNAPSHOT_REFRESH_INTERVAL$3 = Duration.minutes(5);
|
|
79463
|
+
const UPDATE$3 = { resolve: (options) => makeProviderMaintenanceCapabilities({
|
|
79464
|
+
provider: DRIVER_KIND$3,
|
|
79388
79465
|
packageName: null,
|
|
79389
79466
|
updateExecutable: options?.binaryPath?.trim() || "cursor-agent",
|
|
79390
79467
|
updateArgs: ["update"],
|
|
79391
79468
|
updateLockKey: "cursor-agent"
|
|
79392
79469
|
}) };
|
|
79393
|
-
const withInstanceIdentity$
|
|
79470
|
+
const withInstanceIdentity$3 = (input) => (snapshot) => ({
|
|
79394
79471
|
...snapshot,
|
|
79395
79472
|
instanceId: input.instanceId,
|
|
79396
|
-
driver: DRIVER_KIND$
|
|
79473
|
+
driver: DRIVER_KIND$3,
|
|
79397
79474
|
...input.displayName ? { displayName: input.displayName } : {},
|
|
79398
79475
|
...input.accentColor ? { accentColor: input.accentColor } : {},
|
|
79399
79476
|
continuation: { groupKey: input.continuationGroupKey }
|
|
79400
79477
|
});
|
|
79401
79478
|
const CursorDriver = {
|
|
79402
|
-
driverKind: DRIVER_KIND$
|
|
79479
|
+
driverKind: DRIVER_KIND$3,
|
|
79403
79480
|
metadata: {
|
|
79404
79481
|
displayName: "Cursor",
|
|
79405
79482
|
supportsMultipleInstances: true
|
|
@@ -79416,10 +79493,10 @@ const CursorDriver = {
|
|
|
79416
79493
|
const eventLoggers = yield* ProviderEventLoggers;
|
|
79417
79494
|
const processEnv = mergeProviderInstanceEnvironment(environment);
|
|
79418
79495
|
const continuationIdentity = defaultProviderContinuationIdentity({
|
|
79419
|
-
driverKind: DRIVER_KIND$
|
|
79496
|
+
driverKind: DRIVER_KIND$3,
|
|
79420
79497
|
instanceId
|
|
79421
79498
|
});
|
|
79422
|
-
const stampIdentity = withInstanceIdentity$
|
|
79499
|
+
const stampIdentity = withInstanceIdentity$3({
|
|
79423
79500
|
instanceId,
|
|
79424
79501
|
displayName,
|
|
79425
79502
|
accentColor,
|
|
@@ -79429,7 +79506,7 @@ const CursorDriver = {
|
|
|
79429
79506
|
...config,
|
|
79430
79507
|
enabled
|
|
79431
79508
|
};
|
|
79432
|
-
const maintenanceCapabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(UPDATE$
|
|
79509
|
+
const maintenanceCapabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(UPDATE$3, {
|
|
79433
79510
|
binaryPath: effectiveConfig.binaryPath,
|
|
79434
79511
|
env: processEnv
|
|
79435
79512
|
});
|
|
@@ -79457,16 +79534,16 @@ const CursorDriver = {
|
|
|
79457
79534
|
stampIdentity,
|
|
79458
79535
|
httpClient
|
|
79459
79536
|
}),
|
|
79460
|
-
refreshInterval: SNAPSHOT_REFRESH_INTERVAL$
|
|
79537
|
+
refreshInterval: SNAPSHOT_REFRESH_INTERVAL$3
|
|
79461
79538
|
}).pipe(Effect.mapError((cause) => new ProviderDriverError({
|
|
79462
|
-
driver: DRIVER_KIND$
|
|
79539
|
+
driver: DRIVER_KIND$3,
|
|
79463
79540
|
instanceId,
|
|
79464
79541
|
detail: `Failed to build Cursor snapshot: ${cause.message ?? String(cause)}`,
|
|
79465
79542
|
cause
|
|
79466
79543
|
})));
|
|
79467
79544
|
return {
|
|
79468
79545
|
instanceId,
|
|
79469
|
-
driverKind: DRIVER_KIND$
|
|
79546
|
+
driverKind: DRIVER_KIND$3,
|
|
79470
79547
|
continuationIdentity,
|
|
79471
79548
|
displayName,
|
|
79472
79549
|
accentColor,
|
|
@@ -79731,7 +79808,7 @@ function applyGrokAcpModelSelection(input) {
|
|
|
79731
79808
|
//#endregion
|
|
79732
79809
|
//#region src/textGeneration/GrokTextGeneration.ts
|
|
79733
79810
|
const GROK_TIMEOUT_MS = 18e4;
|
|
79734
|
-
const isTextGenerationError = Schema$1.is(TextGenerationError);
|
|
79811
|
+
const isTextGenerationError$1 = Schema$1.is(TextGenerationError);
|
|
79735
79812
|
const makeGrokTextGeneration = Effect.fn("makeGrokTextGeneration")(function* (grokSettings, environment = process.env) {
|
|
79736
79813
|
const crypto = yield* Crypto.Crypto;
|
|
79737
79814
|
const commandSpawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
@@ -79777,7 +79854,7 @@ const makeGrokTextGeneration = Effect.fn("makeGrokTextGeneration")(function* (gr
|
|
|
79777
79854
|
detail: "Grok ACP request timed out."
|
|
79778
79855
|
})),
|
|
79779
79856
|
onSome: (value) => Effect.succeed(value)
|
|
79780
|
-
})), Effect.mapError((cause) => isTextGenerationError(cause) ? cause : new TextGenerationError({
|
|
79857
|
+
})), Effect.mapError((cause) => isTextGenerationError$1(cause) ? cause : new TextGenerationError({
|
|
79781
79858
|
operation,
|
|
79782
79859
|
detail: "Grok ACP request failed.",
|
|
79783
79860
|
cause
|
|
@@ -79792,7 +79869,7 @@ const makeGrokTextGeneration = Effect.fn("makeGrokTextGeneration")(function* (gr
|
|
|
79792
79869
|
detail: "Grok Agent returned invalid structured output.",
|
|
79793
79870
|
cause
|
|
79794
79871
|
})) }));
|
|
79795
|
-
}).pipe(Effect.mapError((cause) => isTextGenerationError(cause) ? cause : new TextGenerationError({
|
|
79872
|
+
}).pipe(Effect.mapError((cause) => isTextGenerationError$1(cause) ? cause : new TextGenerationError({
|
|
79796
79873
|
operation,
|
|
79797
79874
|
detail: "Grok ACP text generation failed.",
|
|
79798
79875
|
cause
|
|
@@ -79872,7 +79949,7 @@ const makeGrokTextGeneration = Effect.fn("makeGrokTextGeneration")(function* (gr
|
|
|
79872
79949
|
//#endregion
|
|
79873
79950
|
//#region src/provider/Layers/GrokAdapter.ts
|
|
79874
79951
|
const encodeUnknownJsonStringExit = Schema$1.encodeUnknownExit(Schema$1.UnknownFromJsonString);
|
|
79875
|
-
const PROVIDER$
|
|
79952
|
+
const PROVIDER$2 = ProviderDriverKind.make("grok");
|
|
79876
79953
|
const GROK_RESUME_VERSION = 1;
|
|
79877
79954
|
function encodeJsonStringForDiagnostics(input) {
|
|
79878
79955
|
const result = encodeUnknownJsonStringExit(input);
|
|
@@ -79899,7 +79976,7 @@ function appendPromptResultToTurn(ctx, turnId, promptParts, result) {
|
|
|
79899
79976
|
}]
|
|
79900
79977
|
}];
|
|
79901
79978
|
}
|
|
79902
|
-
function isRecord(value) {
|
|
79979
|
+
function isRecord$2(value) {
|
|
79903
79980
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
79904
79981
|
}
|
|
79905
79982
|
const resolveNotificationTurnId = (ctx) => ctx.activeTurnId;
|
|
@@ -79909,7 +79986,7 @@ const resolveSessionCallbackTurnId = (sessions, threadId) => {
|
|
|
79909
79986
|
return ctx ? resolveCallbackTurnId(ctx) : void 0;
|
|
79910
79987
|
};
|
|
79911
79988
|
function parseGrokResume(raw) {
|
|
79912
|
-
if (!isRecord(raw)) return void 0;
|
|
79989
|
+
if (!isRecord$2(raw)) return void 0;
|
|
79913
79990
|
if (raw.schemaVersion !== GROK_RESUME_VERSION) return void 0;
|
|
79914
79991
|
if (typeof raw.sessionId !== "string" || !raw.sessionId.trim()) return void 0;
|
|
79915
79992
|
return { sessionId: raw.sessionId.trim() };
|
|
@@ -79944,7 +80021,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
79944
80021
|
const runtimeEventPubSub = yield* PubSub.unbounded();
|
|
79945
80022
|
const nowIso = Effect.map(DateTime.now, DateTime.formatIso);
|
|
79946
80023
|
const randomUUIDv4 = crypto.randomUUIDv4.pipe(Effect.mapError((cause) => new ProviderAdapterRequestError({
|
|
79947
|
-
provider: PROVIDER$
|
|
80024
|
+
provider: PROVIDER$2,
|
|
79948
80025
|
method: "crypto/randomUUIDv4",
|
|
79949
80026
|
detail: "Failed to generate Grok runtime identifier.",
|
|
79950
80027
|
cause
|
|
@@ -79986,7 +80063,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
79986
80063
|
if (options?.errorMessage !== void 0) yield* offerRuntimeEvent({
|
|
79987
80064
|
type: "turn.completed",
|
|
79988
80065
|
...yield* makeEventStamp(),
|
|
79989
|
-
provider: PROVIDER$
|
|
80066
|
+
provider: PROVIDER$2,
|
|
79990
80067
|
threadId,
|
|
79991
80068
|
turnId,
|
|
79992
80069
|
payload: {
|
|
@@ -79997,7 +80074,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
79997
80074
|
else if (options?.completedStopReason !== void 0) yield* offerRuntimeEvent({
|
|
79998
80075
|
type: "turn.completed",
|
|
79999
80076
|
...yield* makeEventStamp(),
|
|
80000
|
-
provider: PROVIDER$
|
|
80077
|
+
provider: PROVIDER$2,
|
|
80001
80078
|
threadId,
|
|
80002
80079
|
turnId,
|
|
80003
80080
|
payload: {
|
|
@@ -80051,7 +80128,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80051
80128
|
if (shouldEmitFailedTurn) yield* offerRuntimeEvent({
|
|
80052
80129
|
type: "turn.completed",
|
|
80053
80130
|
...yield* makeEventStamp(),
|
|
80054
|
-
provider: PROVIDER$
|
|
80131
|
+
provider: PROVIDER$2,
|
|
80055
80132
|
threadId,
|
|
80056
80133
|
turnId: settleTurnId,
|
|
80057
80134
|
payload: {
|
|
@@ -80062,7 +80139,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80062
80139
|
else if (shouldEmitCompletedTurn) yield* offerRuntimeEvent({
|
|
80063
80140
|
type: "turn.completed",
|
|
80064
80141
|
...yield* makeEventStamp(),
|
|
80065
|
-
provider: PROVIDER$
|
|
80142
|
+
provider: PROVIDER$2,
|
|
80066
80143
|
threadId,
|
|
80067
80144
|
turnId: settleTurnId,
|
|
80068
80145
|
payload: {
|
|
@@ -80079,7 +80156,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80079
80156
|
event: {
|
|
80080
80157
|
id: yield* randomUUIDv4,
|
|
80081
80158
|
kind: "notification",
|
|
80082
|
-
provider: PROVIDER$
|
|
80159
|
+
provider: PROVIDER$2,
|
|
80083
80160
|
createdAt: observedAt,
|
|
80084
80161
|
method,
|
|
80085
80162
|
threadId,
|
|
@@ -80097,7 +80174,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80097
80174
|
ctx.lastPlanFingerprint = fingerprint;
|
|
80098
80175
|
yield* offerRuntimeEvent(makeAcpPlanUpdatedEvent({
|
|
80099
80176
|
stamp,
|
|
80100
|
-
provider: PROVIDER$
|
|
80177
|
+
provider: PROVIDER$2,
|
|
80101
80178
|
threadId: ctx.threadId,
|
|
80102
80179
|
turnId,
|
|
80103
80180
|
payload,
|
|
@@ -80109,7 +80186,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80109
80186
|
const requireSession = (threadId) => {
|
|
80110
80187
|
const ctx = sessions.get(threadId);
|
|
80111
80188
|
if (!ctx || ctx.stopped) return Effect.fail(new ProviderAdapterSessionNotFoundError({
|
|
80112
|
-
provider: PROVIDER$
|
|
80189
|
+
provider: PROVIDER$2,
|
|
80113
80190
|
threadId
|
|
80114
80191
|
}));
|
|
80115
80192
|
return Effect.succeed(ctx);
|
|
@@ -80125,19 +80202,19 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80125
80202
|
yield* offerRuntimeEvent({
|
|
80126
80203
|
type: "session.exited",
|
|
80127
80204
|
...yield* makeEventStamp(),
|
|
80128
|
-
provider: PROVIDER$
|
|
80205
|
+
provider: PROVIDER$2,
|
|
80129
80206
|
threadId: ctx.threadId,
|
|
80130
80207
|
payload: { exitKind: "graceful" }
|
|
80131
80208
|
});
|
|
80132
80209
|
});
|
|
80133
80210
|
const startSession = (input) => withThreadLock(input.threadId, Effect.gen(function* () {
|
|
80134
|
-
if (input.provider !== void 0 && input.provider !== PROVIDER$
|
|
80135
|
-
provider: PROVIDER$
|
|
80211
|
+
if (input.provider !== void 0 && input.provider !== PROVIDER$2) return yield* new ProviderAdapterValidationError({
|
|
80212
|
+
provider: PROVIDER$2,
|
|
80136
80213
|
operation: "startSession",
|
|
80137
|
-
issue: `Expected provider '${PROVIDER$
|
|
80214
|
+
issue: `Expected provider '${PROVIDER$2}' but received '${input.provider}'.`
|
|
80138
80215
|
});
|
|
80139
80216
|
if (!input.cwd?.trim()) return yield* new ProviderAdapterValidationError({
|
|
80140
|
-
provider: PROVIDER$
|
|
80217
|
+
provider: PROVIDER$2,
|
|
80141
80218
|
operation: "startSession",
|
|
80142
80219
|
issue: "cwd is required and must be non-empty."
|
|
80143
80220
|
});
|
|
@@ -80153,7 +80230,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80153
80230
|
const resumeSessionId = parseGrokResume(input.resumeCursor)?.sessionId;
|
|
80154
80231
|
const acpNativeLoggers = makeAcpNativeLoggers({
|
|
80155
80232
|
nativeEventLogger,
|
|
80156
|
-
provider: PROVIDER$
|
|
80233
|
+
provider: PROVIDER$2,
|
|
80157
80234
|
threadId: input.threadId
|
|
80158
80235
|
});
|
|
80159
80236
|
const mcpSession = readMcpProviderSession(input.threadId);
|
|
@@ -80178,7 +80255,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80178
80255
|
}] } : {},
|
|
80179
80256
|
...acpNativeLoggers
|
|
80180
80257
|
}).pipe(Effect.provideService(Crypto.Crypto, crypto), Effect.provideService(Scope.Scope, sessionScope), Effect.mapError((cause) => new ProviderAdapterProcessError({
|
|
80181
|
-
provider: PROVIDER$
|
|
80258
|
+
provider: PROVIDER$2,
|
|
80182
80259
|
threadId: input.threadId,
|
|
80183
80260
|
detail: cause.message,
|
|
80184
80261
|
cause
|
|
@@ -80194,7 +80271,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80194
80271
|
yield* offerRuntimeEvent({
|
|
80195
80272
|
type: "user-input.requested",
|
|
80196
80273
|
...yield* makeEventStamp(),
|
|
80197
|
-
provider: PROVIDER$
|
|
80274
|
+
provider: PROVIDER$2,
|
|
80198
80275
|
threadId: input.threadId,
|
|
80199
80276
|
turnId,
|
|
80200
80277
|
requestId: runtimeRequestId,
|
|
@@ -80211,7 +80288,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80211
80288
|
yield* offerRuntimeEvent({
|
|
80212
80289
|
type: "user-input.resolved",
|
|
80213
80290
|
...yield* makeEventStamp(),
|
|
80214
|
-
provider: PROVIDER$
|
|
80291
|
+
provider: PROVIDER$2,
|
|
80215
80292
|
threadId: input.threadId,
|
|
80216
80293
|
turnId,
|
|
80217
80294
|
requestId: runtimeRequestId,
|
|
@@ -80244,7 +80321,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80244
80321
|
pendingApprovals.set(requestId, { decision });
|
|
80245
80322
|
yield* offerRuntimeEvent(makeAcpRequestOpenedEvent({
|
|
80246
80323
|
stamp: yield* makeEventStamp(),
|
|
80247
|
-
provider: PROVIDER$
|
|
80324
|
+
provider: PROVIDER$2,
|
|
80248
80325
|
threadId: input.threadId,
|
|
80249
80326
|
turnId,
|
|
80250
80327
|
requestId: runtimeRequestId,
|
|
@@ -80259,7 +80336,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80259
80336
|
pendingApprovals.delete(requestId);
|
|
80260
80337
|
yield* offerRuntimeEvent(makeAcpRequestResolvedEvent({
|
|
80261
80338
|
stamp: yield* makeEventStamp(),
|
|
80262
|
-
provider: PROVIDER$
|
|
80339
|
+
provider: PROVIDER$2,
|
|
80263
80340
|
threadId: input.threadId,
|
|
80264
80341
|
turnId,
|
|
80265
80342
|
requestId: runtimeRequestId,
|
|
@@ -80273,17 +80350,17 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80273
80350
|
} : { outcome: "cancelled" } };
|
|
80274
80351
|
})));
|
|
80275
80352
|
return yield* acp.start();
|
|
80276
|
-
}).pipe(Effect.mapError((error) => mapAcpToAdapterError(PROVIDER$
|
|
80353
|
+
}).pipe(Effect.mapError((error) => mapAcpToAdapterError(PROVIDER$2, input.threadId, "session/start", error)));
|
|
80277
80354
|
const requestedStartModelId = grokModelSelection?.model ? resolveGrokAcpBaseModelId(grokModelSelection.model) : void 0;
|
|
80278
80355
|
const boundModelId = yield* applyGrokAcpModelSelection({
|
|
80279
80356
|
runtime: acp,
|
|
80280
80357
|
currentModelId: currentGrokModelIdFromSessionSetup(started.sessionSetupResult),
|
|
80281
80358
|
requestedModelId: requestedStartModelId,
|
|
80282
|
-
mapError: (cause) => mapAcpToAdapterError(PROVIDER$
|
|
80359
|
+
mapError: (cause) => mapAcpToAdapterError(PROVIDER$2, input.threadId, "session/set_model", cause)
|
|
80283
80360
|
});
|
|
80284
80361
|
const now = yield* nowIso;
|
|
80285
80362
|
const session = {
|
|
80286
|
-
provider: PROVIDER$
|
|
80363
|
+
provider: PROVIDER$2,
|
|
80287
80364
|
providerInstanceId: boundInstanceId,
|
|
80288
80365
|
status: "ready",
|
|
80289
80366
|
runtimeMode: input.runtimeMode,
|
|
@@ -80328,7 +80405,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80328
80405
|
case "AssistantItemStarted":
|
|
80329
80406
|
yield* offerRuntimeEvent(makeAcpAssistantItemEvent({
|
|
80330
80407
|
stamp,
|
|
80331
|
-
provider: PROVIDER$
|
|
80408
|
+
provider: PROVIDER$2,
|
|
80332
80409
|
threadId: ctx.threadId,
|
|
80333
80410
|
turnId: notificationTurnId,
|
|
80334
80411
|
itemId: event.itemId,
|
|
@@ -80338,7 +80415,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80338
80415
|
case "AssistantItemCompleted":
|
|
80339
80416
|
yield* offerRuntimeEvent(makeAcpAssistantItemEvent({
|
|
80340
80417
|
stamp,
|
|
80341
|
-
provider: PROVIDER$
|
|
80418
|
+
provider: PROVIDER$2,
|
|
80342
80419
|
threadId: ctx.threadId,
|
|
80343
80420
|
turnId: notificationTurnId,
|
|
80344
80421
|
itemId: event.itemId,
|
|
@@ -80351,7 +80428,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80351
80428
|
case "ToolCallUpdated":
|
|
80352
80429
|
yield* offerRuntimeEvent(makeAcpToolCallEvent({
|
|
80353
80430
|
stamp,
|
|
80354
|
-
provider: PROVIDER$
|
|
80431
|
+
provider: PROVIDER$2,
|
|
80355
80432
|
threadId: ctx.threadId,
|
|
80356
80433
|
turnId: notificationTurnId,
|
|
80357
80434
|
toolCall: event.toolCall,
|
|
@@ -80361,7 +80438,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80361
80438
|
case "ContentDelta":
|
|
80362
80439
|
yield* offerRuntimeEvent(makeAcpContentDeltaEvent({
|
|
80363
80440
|
stamp,
|
|
80364
|
-
provider: PROVIDER$
|
|
80441
|
+
provider: PROVIDER$2,
|
|
80365
80442
|
threadId: ctx.threadId,
|
|
80366
80443
|
turnId: notificationTurnId,
|
|
80367
80444
|
...event.itemId ? { itemId: event.itemId } : {},
|
|
@@ -80376,14 +80453,14 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80376
80453
|
yield* offerRuntimeEvent({
|
|
80377
80454
|
type: "session.started",
|
|
80378
80455
|
...yield* makeEventStamp(),
|
|
80379
|
-
provider: PROVIDER$
|
|
80456
|
+
provider: PROVIDER$2,
|
|
80380
80457
|
threadId: input.threadId,
|
|
80381
80458
|
payload: { resume: started.initializeResult }
|
|
80382
80459
|
});
|
|
80383
80460
|
yield* offerRuntimeEvent({
|
|
80384
80461
|
type: "session.state.changed",
|
|
80385
80462
|
...yield* makeEventStamp(),
|
|
80386
|
-
provider: PROVIDER$
|
|
80463
|
+
provider: PROVIDER$2,
|
|
80387
80464
|
threadId: input.threadId,
|
|
80388
80465
|
payload: {
|
|
80389
80466
|
state: "ready",
|
|
@@ -80393,7 +80470,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80393
80470
|
yield* offerRuntimeEvent({
|
|
80394
80471
|
type: "thread.started",
|
|
80395
80472
|
...yield* makeEventStamp(),
|
|
80396
|
-
provider: PROVIDER$
|
|
80473
|
+
provider: PROVIDER$2,
|
|
80397
80474
|
threadId: input.threadId,
|
|
80398
80475
|
payload: { providerThreadId: started.sessionId }
|
|
80399
80476
|
});
|
|
@@ -80419,7 +80496,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80419
80496
|
runtime: ctx.acp,
|
|
80420
80497
|
currentModelId: ctx.currentModelId,
|
|
80421
80498
|
requestedModelId: requestedTurnModelId,
|
|
80422
|
-
mapError: (cause) => mapAcpToAdapterError(PROVIDER$
|
|
80499
|
+
mapError: (cause) => mapAcpToAdapterError(PROVIDER$2, input.threadId, "session/set_model", cause)
|
|
80423
80500
|
});
|
|
80424
80501
|
const text = input.input?.trim();
|
|
80425
80502
|
const imagePromptParts = yield* Effect.forEach(input.attachments ?? [], (attachment) => Effect.gen(function* () {
|
|
@@ -80428,12 +80505,12 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80428
80505
|
attachment
|
|
80429
80506
|
});
|
|
80430
80507
|
if (!attachmentPath) return yield* new ProviderAdapterRequestError({
|
|
80431
|
-
provider: PROVIDER$
|
|
80508
|
+
provider: PROVIDER$2,
|
|
80432
80509
|
method: "session/prompt",
|
|
80433
80510
|
detail: `Invalid attachment id '${attachment.id}'.`
|
|
80434
80511
|
});
|
|
80435
80512
|
const bytes = yield* fileSystem.readFile(attachmentPath).pipe(Effect.mapError((cause) => new ProviderAdapterRequestError({
|
|
80436
|
-
provider: PROVIDER$
|
|
80513
|
+
provider: PROVIDER$2,
|
|
80437
80514
|
method: "session/prompt",
|
|
80438
80515
|
detail: cause.message,
|
|
80439
80516
|
cause
|
|
@@ -80449,7 +80526,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80449
80526
|
text
|
|
80450
80527
|
}] : [], ...imagePromptParts];
|
|
80451
80528
|
if (promptParts.length === 0) return yield* new ProviderAdapterValidationError({
|
|
80452
|
-
provider: PROVIDER$
|
|
80529
|
+
provider: PROVIDER$2,
|
|
80453
80530
|
operation: "sendTurn",
|
|
80454
80531
|
issue: "Turn requires non-empty text or attachments."
|
|
80455
80532
|
});
|
|
@@ -80463,7 +80540,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80463
80540
|
settleAllPrompts: true
|
|
80464
80541
|
});
|
|
80465
80542
|
return yield* new ProviderAdapterRequestError({
|
|
80466
|
-
provider: PROVIDER$
|
|
80543
|
+
provider: PROVIDER$2,
|
|
80467
80544
|
method: "session/prompt",
|
|
80468
80545
|
detail: "Grok prompt was interrupted during preparation."
|
|
80469
80546
|
});
|
|
@@ -80479,7 +80556,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80479
80556
|
if (steeringTurnId === void 0) yield* offerRuntimeEvent({
|
|
80480
80557
|
type: "turn.started",
|
|
80481
80558
|
...yield* makeEventStamp(),
|
|
80482
|
-
provider: PROVIDER$
|
|
80559
|
+
provider: PROVIDER$2,
|
|
80483
80560
|
threadId: input.threadId,
|
|
80484
80561
|
turnId,
|
|
80485
80562
|
payload: displayModel ? { model: displayModel } : {}
|
|
@@ -80505,7 +80582,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80505
80582
|
const promptResultRef = yield* Ref.make(void 0);
|
|
80506
80583
|
const promptFailureMessageRef = yield* Ref.make(void 0);
|
|
80507
80584
|
return yield* Effect.gen(function* () {
|
|
80508
|
-
const result = yield* prepared.acp.prompt({ prompt: prepared.promptParts }).pipe(Effect.tap((promptResult) => Effect.all([Ref.set(promptRpcSucceeded, true), Ref.set(promptResultRef, promptResult)])), Effect.tapError((error) => Ref.set(promptFailureMessageRef, mapAcpToAdapterError(PROVIDER$
|
|
80585
|
+
const result = yield* prepared.acp.prompt({ prompt: prepared.promptParts }).pipe(Effect.tap((promptResult) => Effect.all([Ref.set(promptRpcSucceeded, true), Ref.set(promptResultRef, promptResult)])), Effect.tapError((error) => Ref.set(promptFailureMessageRef, mapAcpToAdapterError(PROVIDER$2, input.threadId, "session/prompt", error).message).pipe(Effect.andThen(prepared.acp.drainEvents))), Effect.mapError((error) => mapAcpToAdapterError(PROVIDER$2, input.threadId, "session/prompt", error)));
|
|
80509
80586
|
return yield* withThreadLock(input.threadId, Effect.gen(function* () {
|
|
80510
80587
|
const ctx = yield* requireSession(input.threadId);
|
|
80511
80588
|
if (ctx.acpSessionId !== prepared.acpSessionId) {
|
|
@@ -80515,7 +80592,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80515
80592
|
});
|
|
80516
80593
|
yield* Ref.set(promptSettled, true);
|
|
80517
80594
|
return yield* new ProviderAdapterRequestError({
|
|
80518
|
-
provider: PROVIDER$
|
|
80595
|
+
provider: PROVIDER$2,
|
|
80519
80596
|
method: "session/prompt",
|
|
80520
80597
|
detail: "Grok session changed before the turn completed."
|
|
80521
80598
|
});
|
|
@@ -80570,7 +80647,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80570
80647
|
yield* offerRuntimeEvent({
|
|
80571
80648
|
type: "turn.completed",
|
|
80572
80649
|
...yield* makeEventStamp(),
|
|
80573
|
-
provider: PROVIDER$
|
|
80650
|
+
provider: PROVIDER$2,
|
|
80574
80651
|
threadId: input.threadId,
|
|
80575
80652
|
turnId: prepared.turnId,
|
|
80576
80653
|
payload: {
|
|
@@ -80640,7 +80717,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80640
80717
|
const interruptedTurnId = observed.interruptedTurnId ?? turnId ?? activeTurnId ?? ctx.session.activeTurnId;
|
|
80641
80718
|
yield* settlePendingApprovalsAsCancelled(ctx.pendingApprovals);
|
|
80642
80719
|
yield* settlePendingUserInputsAsCancelled(ctx.pendingUserInputs);
|
|
80643
|
-
yield* Effect.ignore(ctx.acp.cancel.pipe(Effect.mapError((error) => mapAcpToAdapterError(PROVIDER$
|
|
80720
|
+
yield* Effect.ignore(ctx.acp.cancel.pipe(Effect.mapError((error) => mapAcpToAdapterError(PROVIDER$2, threadId, "session/cancel", error))));
|
|
80644
80721
|
if (interruptedTurnId) {
|
|
80645
80722
|
ctx.interruptedTurnIds.add(interruptedTurnId);
|
|
80646
80723
|
yield* settlePromptInFlight(threadId, interruptedTurnId, ctx.acpSessionId, {
|
|
@@ -80663,7 +80740,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80663
80740
|
const respondToRequest = (threadId, requestId, decision) => Effect.gen(function* () {
|
|
80664
80741
|
const pending = (yield* requireSession(threadId)).pendingApprovals.get(requestId);
|
|
80665
80742
|
if (!pending) return yield* new ProviderAdapterRequestError({
|
|
80666
|
-
provider: PROVIDER$
|
|
80743
|
+
provider: PROVIDER$2,
|
|
80667
80744
|
method: "session/request_permission",
|
|
80668
80745
|
detail: `Unknown pending approval request: ${requestId}`
|
|
80669
80746
|
});
|
|
@@ -80672,7 +80749,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80672
80749
|
const respondToUserInput = (threadId, requestId, answers) => Effect.gen(function* () {
|
|
80673
80750
|
const pending = (yield* requireSession(threadId)).pendingUserInputs.get(requestId);
|
|
80674
80751
|
if (!pending) return yield* new ProviderAdapterRequestError({
|
|
80675
|
-
provider: PROVIDER$
|
|
80752
|
+
provider: PROVIDER$2,
|
|
80676
80753
|
method: "_x.ai/ask_user_question",
|
|
80677
80754
|
detail: `Unknown pending user-input request: ${requestId}`
|
|
80678
80755
|
});
|
|
@@ -80690,12 +80767,12 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80690
80767
|
const rollbackThread = (threadId, numTurns) => Effect.gen(function* () {
|
|
80691
80768
|
yield* requireSession(threadId);
|
|
80692
80769
|
if (!Number.isInteger(numTurns) || numTurns < 1) return yield* new ProviderAdapterValidationError({
|
|
80693
|
-
provider: PROVIDER$
|
|
80770
|
+
provider: PROVIDER$2,
|
|
80694
80771
|
operation: "rollbackThread",
|
|
80695
80772
|
issue: "numTurns must be an integer >= 1."
|
|
80696
80773
|
});
|
|
80697
80774
|
return yield* new ProviderAdapterRequestError({
|
|
80698
|
-
provider: PROVIDER$
|
|
80775
|
+
provider: PROVIDER$2,
|
|
80699
80776
|
method: "thread/rollback",
|
|
80700
80777
|
detail: "Grok ACP sessions do not support provider-side rollback yet."
|
|
80701
80778
|
});
|
|
@@ -80713,7 +80790,7 @@ function makeGrokAdapter(grokSettings, options) {
|
|
|
80713
80790
|
yield* Effect.addFinalizer(() => Effect.ignore(stopAll()).pipe(Effect.tap(() => PubSub.shutdown(runtimeEventPubSub)), Effect.tap(() => managedNativeEventLogger?.close() ?? Effect.void)));
|
|
80714
80791
|
const streamEvents = Stream.fromPubSub(runtimeEventPubSub);
|
|
80715
80792
|
return {
|
|
80716
|
-
provider: PROVIDER$
|
|
80793
|
+
provider: PROVIDER$2,
|
|
80717
80794
|
capabilities: { sessionModelSwitch: "in-session" },
|
|
80718
80795
|
startSession,
|
|
80719
80796
|
sendTurn,
|
|
@@ -80738,14 +80815,14 @@ const GROK_PRESENTATION = {
|
|
|
80738
80815
|
showInteractionModeToggle: false,
|
|
80739
80816
|
requiresNewThreadForModelChange: true
|
|
80740
80817
|
};
|
|
80741
|
-
const EMPTY_CAPABILITIES = createModelCapabilities({ optionDescriptors: [] });
|
|
80742
|
-
const VERSION_PROBE_TIMEOUT_MS = 4e3;
|
|
80818
|
+
const EMPTY_CAPABILITIES$1 = createModelCapabilities({ optionDescriptors: [] });
|
|
80819
|
+
const VERSION_PROBE_TIMEOUT_MS$1 = 4e3;
|
|
80743
80820
|
const GROK_ACP_MODEL_DISCOVERY_TIMEOUT_MS = 15e3;
|
|
80744
80821
|
const GROK_BUILT_IN_MODELS = [{
|
|
80745
80822
|
slug: "grok-build",
|
|
80746
80823
|
name: "Grok Build",
|
|
80747
80824
|
isCustom: false,
|
|
80748
|
-
capabilities: EMPTY_CAPABILITIES
|
|
80825
|
+
capabilities: EMPTY_CAPABILITIES$1
|
|
80749
80826
|
}];
|
|
80750
80827
|
function buildInitialGrokProviderSnapshot(grokSettings) {
|
|
80751
80828
|
return Effect.gen(function* () {
|
|
@@ -80780,7 +80857,7 @@ function buildInitialGrokProviderSnapshot(grokSettings) {
|
|
|
80780
80857
|
});
|
|
80781
80858
|
}
|
|
80782
80859
|
function grokModelsFromSettings(customModels, builtInModels = GROK_BUILT_IN_MODELS) {
|
|
80783
|
-
return providerModelsFromSettings(builtInModels, customModels ?? [], EMPTY_CAPABILITIES);
|
|
80860
|
+
return providerModelsFromSettings(builtInModels, customModels ?? [], EMPTY_CAPABILITIES$1);
|
|
80784
80861
|
}
|
|
80785
80862
|
function buildGrokDiscoveredModelsFromSessionModelState(modelState) {
|
|
80786
80863
|
if (!modelState || modelState.availableModels.length === 0) return [];
|
|
@@ -80793,7 +80870,7 @@ function buildGrokDiscoveredModelsFromSessionModelState(modelState) {
|
|
|
80793
80870
|
slug,
|
|
80794
80871
|
name: model.name.trim() || slug,
|
|
80795
80872
|
isCustom: false,
|
|
80796
|
-
capabilities: EMPTY_CAPABILITIES
|
|
80873
|
+
capabilities: EMPTY_CAPABILITIES$1
|
|
80797
80874
|
};
|
|
80798
80875
|
}).filter((model) => model !== void 0);
|
|
80799
80876
|
}
|
|
@@ -80833,7 +80910,7 @@ const checkGrokProviderStatus = Effect.fn("checkGrokProviderStatus")(function* (
|
|
|
80833
80910
|
message: "Grok is disabled in P4Code settings."
|
|
80834
80911
|
}
|
|
80835
80912
|
});
|
|
80836
|
-
const versionResult = yield* runGrokVersionCommand(grokSettings, environment).pipe(Effect.timeoutOption(VERSION_PROBE_TIMEOUT_MS), Effect.result);
|
|
80913
|
+
const versionResult = yield* runGrokVersionCommand(grokSettings, environment).pipe(Effect.timeoutOption(VERSION_PROBE_TIMEOUT_MS$1), Effect.result);
|
|
80837
80914
|
if (Result.isFailure(versionResult)) {
|
|
80838
80915
|
const error = versionResult.failure;
|
|
80839
80916
|
const missing = isCommandMissingCause(error);
|
|
@@ -80942,22 +81019,22 @@ const enrichGrokSnapshot = (input) => {
|
|
|
80942
81019
|
//#endregion
|
|
80943
81020
|
//#region src/provider/Drivers/GrokDriver.ts
|
|
80944
81021
|
const decodeGrokSettings = Schema$1.decodeSync(GrokSettings);
|
|
80945
|
-
const DRIVER_KIND$
|
|
80946
|
-
const SNAPSHOT_REFRESH_INTERVAL$
|
|
80947
|
-
const UPDATE$
|
|
80948
|
-
provider: DRIVER_KIND$
|
|
81022
|
+
const DRIVER_KIND$2 = ProviderDriverKind.make("grok");
|
|
81023
|
+
const SNAPSHOT_REFRESH_INTERVAL$2 = Duration.minutes(5);
|
|
81024
|
+
const UPDATE$2 = makeStaticProviderMaintenanceResolver(makeManualOnlyProviderMaintenanceCapabilities({
|
|
81025
|
+
provider: DRIVER_KIND$2,
|
|
80949
81026
|
packageName: null
|
|
80950
81027
|
}));
|
|
80951
|
-
const withInstanceIdentity$
|
|
81028
|
+
const withInstanceIdentity$2 = (input) => (snapshot) => ({
|
|
80952
81029
|
...snapshot,
|
|
80953
81030
|
instanceId: input.instanceId,
|
|
80954
|
-
driver: DRIVER_KIND$
|
|
81031
|
+
driver: DRIVER_KIND$2,
|
|
80955
81032
|
...input.displayName ? { displayName: input.displayName } : {},
|
|
80956
81033
|
...input.accentColor ? { accentColor: input.accentColor } : {},
|
|
80957
81034
|
continuation: { groupKey: input.continuationGroupKey }
|
|
80958
81035
|
});
|
|
80959
81036
|
const GrokDriver = {
|
|
80960
|
-
driverKind: DRIVER_KIND$
|
|
81037
|
+
driverKind: DRIVER_KIND$2,
|
|
80961
81038
|
metadata: {
|
|
80962
81039
|
displayName: "Grok",
|
|
80963
81040
|
supportsMultipleInstances: true
|
|
@@ -80972,10 +81049,10 @@ const GrokDriver = {
|
|
|
80972
81049
|
const eventLoggers = yield* ProviderEventLoggers;
|
|
80973
81050
|
const processEnv = mergeProviderInstanceEnvironment(environment);
|
|
80974
81051
|
const continuationIdentity = defaultProviderContinuationIdentity({
|
|
80975
|
-
driverKind: DRIVER_KIND$
|
|
81052
|
+
driverKind: DRIVER_KIND$2,
|
|
80976
81053
|
instanceId
|
|
80977
81054
|
});
|
|
80978
|
-
const stampIdentity = withInstanceIdentity$
|
|
81055
|
+
const stampIdentity = withInstanceIdentity$2({
|
|
80979
81056
|
instanceId,
|
|
80980
81057
|
displayName,
|
|
80981
81058
|
accentColor,
|
|
@@ -80985,7 +81062,7 @@ const GrokDriver = {
|
|
|
80985
81062
|
...config,
|
|
80986
81063
|
enabled
|
|
80987
81064
|
};
|
|
80988
|
-
const maintenanceCapabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(UPDATE$
|
|
81065
|
+
const maintenanceCapabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(UPDATE$2, {
|
|
80989
81066
|
binaryPath: effectiveConfig.binaryPath,
|
|
80990
81067
|
env: processEnv
|
|
80991
81068
|
});
|
|
@@ -81011,11 +81088,1467 @@ const GrokDriver = {
|
|
|
81011
81088
|
publishSnapshot,
|
|
81012
81089
|
httpClient
|
|
81013
81090
|
}),
|
|
81091
|
+
refreshInterval: SNAPSHOT_REFRESH_INTERVAL$2
|
|
81092
|
+
}).pipe(Effect.mapError((cause) => new ProviderDriverError({
|
|
81093
|
+
driver: DRIVER_KIND$2,
|
|
81094
|
+
instanceId,
|
|
81095
|
+
detail: `Failed to build Grok snapshot: ${cause.message ?? String(cause)}`,
|
|
81096
|
+
cause
|
|
81097
|
+
})));
|
|
81098
|
+
return {
|
|
81099
|
+
instanceId,
|
|
81100
|
+
driverKind: DRIVER_KIND$2,
|
|
81101
|
+
continuationIdentity,
|
|
81102
|
+
displayName,
|
|
81103
|
+
accentColor,
|
|
81104
|
+
enabled,
|
|
81105
|
+
snapshot,
|
|
81106
|
+
adapter,
|
|
81107
|
+
textGeneration
|
|
81108
|
+
};
|
|
81109
|
+
})
|
|
81110
|
+
};
|
|
81111
|
+
/**
|
|
81112
|
+
* Build the argument vector for one turn.
|
|
81113
|
+
*
|
|
81114
|
+
* Approval policy is the load-bearing decision here. A headless Muse run has
|
|
81115
|
+
* no channel to answer an approval prompt — the CLI only offers
|
|
81116
|
+
* `--disable-approval` (keep the OS sandbox) and `--yolo` (drop approval and
|
|
81117
|
+
* the sandbox, and trust the workspace). P4Code owns the user-facing runtime
|
|
81118
|
+
* mode, so it maps onto those two postures:
|
|
81119
|
+
*
|
|
81120
|
+
* - `full-access` → `--yolo`
|
|
81121
|
+
* - everything else → `--disable-approval --trust-workspace`, leaving the
|
|
81122
|
+
* sandbox to contain what runs.
|
|
81123
|
+
*
|
|
81124
|
+
* `approval-required` cannot be honoured; the adapter emits a
|
|
81125
|
+
* `config.warning` for it rather than silently pretending otherwise.
|
|
81126
|
+
*/
|
|
81127
|
+
function buildMuseExecArgs(input) {
|
|
81128
|
+
const args = [
|
|
81129
|
+
"exec",
|
|
81130
|
+
"--json",
|
|
81131
|
+
"--session-id",
|
|
81132
|
+
input.sessionId
|
|
81133
|
+
];
|
|
81134
|
+
if (input.model) args.push("--model", input.model);
|
|
81135
|
+
if (input.reasoningEffort) args.push("--reasoning-effort", input.reasoningEffort);
|
|
81136
|
+
if (input.baseUrl) args.push("--base-url", input.baseUrl);
|
|
81137
|
+
if (input.runtimeMode === "full-access") args.push("--yolo");
|
|
81138
|
+
else {
|
|
81139
|
+
args.push("--disable-approval", "--trust-workspace");
|
|
81140
|
+
switch (input.sandboxMode) {
|
|
81141
|
+
case "danger-full-access":
|
|
81142
|
+
args.push("--disable-sandbox");
|
|
81143
|
+
break;
|
|
81144
|
+
case "read-only":
|
|
81145
|
+
args.push("--disable-write", "--disable-shell");
|
|
81146
|
+
break;
|
|
81147
|
+
default: break;
|
|
81148
|
+
}
|
|
81149
|
+
}
|
|
81150
|
+
for (const imagePath of input.imagePaths ?? []) args.push("--image", imagePath);
|
|
81151
|
+
args.push(input.prompt);
|
|
81152
|
+
return args;
|
|
81153
|
+
}
|
|
81154
|
+
/** `muse --version` argv, used by the provider status probe. */
|
|
81155
|
+
const MUSE_VERSION_ARGS = ["--version"];
|
|
81156
|
+
/**
|
|
81157
|
+
* Whether a runtime mode asks for interactive approvals that Muse Code
|
|
81158
|
+
* cannot deliver headlessly.
|
|
81159
|
+
*/
|
|
81160
|
+
function museApprovalsUnsupported(runtimeMode) {
|
|
81161
|
+
return runtimeMode === "approval-required";
|
|
81162
|
+
}
|
|
81163
|
+
//#endregion
|
|
81164
|
+
//#region src/provider/muse/MuseExecEvents.ts
|
|
81165
|
+
/**
|
|
81166
|
+
* MuseExecEvents — pure translation of `muse exec --json` JSONL records into
|
|
81167
|
+
* canonical `ProviderRuntimeEvent`s.
|
|
81168
|
+
*
|
|
81169
|
+
* Muse Code has no ACP or app-server surface (verified against CLI
|
|
81170
|
+
* 0.1.0-R708.1): the only scriptable path is `muse exec --json`, which runs
|
|
81171
|
+
* one prompt to completion and prints one JSON object per line. Multi-turn
|
|
81172
|
+
* threads are rebuilt by re-invoking with `--session-id`.
|
|
81173
|
+
*
|
|
81174
|
+
* Everything here is a pure function over a caller-owned state record so the
|
|
81175
|
+
* mapping can be tested against captured CLI output without spawning a
|
|
81176
|
+
* process. Process ownership lives in `MuseExecRuntime`.
|
|
81177
|
+
*
|
|
81178
|
+
* @module provider/muse/MuseExecEvents
|
|
81179
|
+
*/
|
|
81180
|
+
/** Longest tool result text carried on an `item.completed` detail. */
|
|
81181
|
+
const MAX_TOOL_DETAIL_CHARS = 2e3;
|
|
81182
|
+
function makeMuseExecTurnState() {
|
|
81183
|
+
return {
|
|
81184
|
+
modelId: void 0,
|
|
81185
|
+
assistantItemStarted: false,
|
|
81186
|
+
assistantText: "",
|
|
81187
|
+
toolNameByTaskId: /* @__PURE__ */ new Map(),
|
|
81188
|
+
taskIdByCallId: /* @__PURE__ */ new Map(),
|
|
81189
|
+
settledToolTaskIds: /* @__PURE__ */ new Set(),
|
|
81190
|
+
terminal: void 0
|
|
81191
|
+
};
|
|
81192
|
+
}
|
|
81193
|
+
/**
|
|
81194
|
+
* Decode one line of `muse exec --json`. Returns `undefined` for blank lines
|
|
81195
|
+
* and for anything that is not a JSON object with a string `payload_type`, so
|
|
81196
|
+
* a stray line can never abort a turn.
|
|
81197
|
+
*/
|
|
81198
|
+
function parseMuseExecLine(line) {
|
|
81199
|
+
const trimmed = line.trim();
|
|
81200
|
+
if (trimmed.length === 0) return void 0;
|
|
81201
|
+
let decoded;
|
|
81202
|
+
try {
|
|
81203
|
+
decoded = JSON.parse(trimmed);
|
|
81204
|
+
} catch {
|
|
81205
|
+
return;
|
|
81206
|
+
}
|
|
81207
|
+
if (!isRecord$1(decoded)) return void 0;
|
|
81208
|
+
const payloadType = decoded["payload_type"];
|
|
81209
|
+
if (typeof payloadType !== "string") return void 0;
|
|
81210
|
+
const payload = isRecord$1(decoded["payload"]) ? decoded["payload"] : {};
|
|
81211
|
+
const stream = isRecord$1(decoded["stream"]) ? decoded["stream"] : void 0;
|
|
81212
|
+
const streamId = stream?.["id"];
|
|
81213
|
+
const sequence = decoded["sequence"];
|
|
81214
|
+
return {
|
|
81215
|
+
payloadType,
|
|
81216
|
+
payload,
|
|
81217
|
+
sequence: typeof sequence === "number" ? sequence : void 0,
|
|
81218
|
+
sessionId: stream?.["kind"] === "session" && typeof streamId === "string" ? streamId : void 0
|
|
81219
|
+
};
|
|
81220
|
+
}
|
|
81221
|
+
/**
|
|
81222
|
+
* Map one CLI record onto zero or more event drafts, mutating `state`.
|
|
81223
|
+
*
|
|
81224
|
+
* The CLI stream is deliberately lossy compared with the persisted session
|
|
81225
|
+
* log: tool call *arguments* and token usage never appear on stdout. Those
|
|
81226
|
+
* are recovered separately from `session.jsonl` (see `MuseSessionLog`).
|
|
81227
|
+
*/
|
|
81228
|
+
function mapMuseExecRecord(input) {
|
|
81229
|
+
const { record, state, context } = input;
|
|
81230
|
+
const payload = record.payload;
|
|
81231
|
+
switch (record.payloadType) {
|
|
81232
|
+
case "run.model.configured": {
|
|
81233
|
+
const modelId = stringField(payload, "model_id");
|
|
81234
|
+
if (modelId) state.modelId = modelId;
|
|
81235
|
+
return [(stamp) => ({
|
|
81236
|
+
type: "session.configured",
|
|
81237
|
+
...stamp,
|
|
81238
|
+
...base(context),
|
|
81239
|
+
payload: { config: payload },
|
|
81240
|
+
raw: rawFrom(record)
|
|
81241
|
+
})];
|
|
81242
|
+
}
|
|
81243
|
+
case "run.lifecycle.started": return [(stamp) => ({
|
|
81244
|
+
type: "turn.started",
|
|
81245
|
+
...stamp,
|
|
81246
|
+
...base(context),
|
|
81247
|
+
payload: state.modelId ? { model: state.modelId } : {},
|
|
81248
|
+
raw: rawFrom(record)
|
|
81249
|
+
})];
|
|
81250
|
+
case "run.output.delta": {
|
|
81251
|
+
const text = stringField(payload, "text");
|
|
81252
|
+
if (text === void 0 || text.length === 0) return [];
|
|
81253
|
+
return appendAssistantText({
|
|
81254
|
+
text,
|
|
81255
|
+
state,
|
|
81256
|
+
context,
|
|
81257
|
+
record
|
|
81258
|
+
});
|
|
81259
|
+
}
|
|
81260
|
+
case "task.lifecycle.proposed": {
|
|
81261
|
+
const event = eventField(payload);
|
|
81262
|
+
const taskId = stringField(event, "task_id");
|
|
81263
|
+
const toolName = toolNameFromTaskKind(stringField(event, "task_kind"));
|
|
81264
|
+
if (!taskId || !toolName) return [];
|
|
81265
|
+
state.toolNameByTaskId.set(taskId, toolName);
|
|
81266
|
+
return [(stamp) => ({
|
|
81267
|
+
type: "item.started",
|
|
81268
|
+
...stamp,
|
|
81269
|
+
...base(context),
|
|
81270
|
+
itemId: RuntimeItemId.make(taskId),
|
|
81271
|
+
payload: {
|
|
81272
|
+
itemType: itemTypeForToolName(toolName),
|
|
81273
|
+
status: "inProgress",
|
|
81274
|
+
title: toolName
|
|
81275
|
+
},
|
|
81276
|
+
raw: rawFrom(record)
|
|
81277
|
+
})];
|
|
81278
|
+
}
|
|
81279
|
+
case "task.lifecycle.side_effect_intent": {
|
|
81280
|
+
const event = eventField(payload);
|
|
81281
|
+
const taskId = stringField(event, "task_id");
|
|
81282
|
+
const callId = toolCallIdFromIdempotencyKey(stringField(event, "idempotency_key"));
|
|
81283
|
+
if (taskId && callId) state.taskIdByCallId.set(callId, taskId);
|
|
81284
|
+
return [];
|
|
81285
|
+
}
|
|
81286
|
+
case "task.lifecycle.output": {
|
|
81287
|
+
const event = eventField(payload);
|
|
81288
|
+
const taskId = stringField(event, "task_id");
|
|
81289
|
+
const chunk = stringField(event, "chunk");
|
|
81290
|
+
if (!taskId || !chunk) return [];
|
|
81291
|
+
const toolName = state.toolNameByTaskId.get(taskId);
|
|
81292
|
+
if (!toolName) return [];
|
|
81293
|
+
const streamKind = itemTypeForToolName(toolName) === "command_execution" ? "command_output" : "file_change_output";
|
|
81294
|
+
return [(stamp) => ({
|
|
81295
|
+
type: "content.delta",
|
|
81296
|
+
...stamp,
|
|
81297
|
+
...base(context),
|
|
81298
|
+
itemId: RuntimeItemId.make(taskId),
|
|
81299
|
+
payload: {
|
|
81300
|
+
streamKind,
|
|
81301
|
+
delta: chunk
|
|
81302
|
+
},
|
|
81303
|
+
raw: rawFrom(record)
|
|
81304
|
+
})];
|
|
81305
|
+
}
|
|
81306
|
+
case "tool.result": {
|
|
81307
|
+
const callId = stringField(payload, "call_id");
|
|
81308
|
+
const taskId = callId ? state.taskIdByCallId.get(callId) : void 0;
|
|
81309
|
+
if (!taskId) return [];
|
|
81310
|
+
const toolName = state.toolNameByTaskId.get(taskId);
|
|
81311
|
+
state.settledToolTaskIds.add(taskId);
|
|
81312
|
+
const failed = stringField(recordField(payload, "correlation_facts"), "outcome") === "error";
|
|
81313
|
+
const detail = truncate(stringField(payload, "text"), MAX_TOOL_DETAIL_CHARS);
|
|
81314
|
+
const editFacts = recordField(payload, "edit_facts");
|
|
81315
|
+
return [(stamp) => ({
|
|
81316
|
+
type: "item.completed",
|
|
81317
|
+
...stamp,
|
|
81318
|
+
...base(context),
|
|
81319
|
+
itemId: RuntimeItemId.make(taskId),
|
|
81320
|
+
payload: {
|
|
81321
|
+
itemType: itemTypeForToolName(toolName),
|
|
81322
|
+
status: failed ? "failed" : "completed",
|
|
81323
|
+
...toolName ? { title: toolName } : {},
|
|
81324
|
+
...detail ? { detail } : {},
|
|
81325
|
+
...editFacts ? { data: editFacts } : {}
|
|
81326
|
+
},
|
|
81327
|
+
raw: rawFrom(record)
|
|
81328
|
+
})];
|
|
81329
|
+
}
|
|
81330
|
+
case "task.lifecycle.failed": {
|
|
81331
|
+
const event = eventField(payload);
|
|
81332
|
+
const taskId = stringField(event, "task_id");
|
|
81333
|
+
if (!taskId) return [];
|
|
81334
|
+
const toolName = state.toolNameByTaskId.get(taskId);
|
|
81335
|
+
if (!toolName || state.settledToolTaskIds.has(taskId)) return [];
|
|
81336
|
+
state.settledToolTaskIds.add(taskId);
|
|
81337
|
+
const detail = truncate(stringField(event, "reason"), MAX_TOOL_DETAIL_CHARS);
|
|
81338
|
+
return [(stamp) => ({
|
|
81339
|
+
type: "item.completed",
|
|
81340
|
+
...stamp,
|
|
81341
|
+
...base(context),
|
|
81342
|
+
itemId: RuntimeItemId.make(taskId),
|
|
81343
|
+
payload: {
|
|
81344
|
+
itemType: itemTypeForToolName(toolName),
|
|
81345
|
+
status: "failed",
|
|
81346
|
+
title: toolName,
|
|
81347
|
+
...detail ? { detail } : {}
|
|
81348
|
+
},
|
|
81349
|
+
raw: rawFrom(record)
|
|
81350
|
+
})];
|
|
81351
|
+
}
|
|
81352
|
+
default: break;
|
|
81353
|
+
}
|
|
81354
|
+
if (record.payloadType.startsWith("run.terminal.")) return mapTerminalRecord({
|
|
81355
|
+
record,
|
|
81356
|
+
state,
|
|
81357
|
+
context
|
|
81358
|
+
});
|
|
81359
|
+
return [];
|
|
81360
|
+
}
|
|
81361
|
+
/**
|
|
81362
|
+
* Terminal record handling. The final `text` is the authoritative assistant
|
|
81363
|
+
* message and is a superset of the streamed deltas (Muse streams the visible
|
|
81364
|
+
* prefix only), so any remainder is flushed as one last delta before the
|
|
81365
|
+
* assistant item closes.
|
|
81366
|
+
*/
|
|
81367
|
+
function mapTerminalRecord(input) {
|
|
81368
|
+
const { record, state, context } = input;
|
|
81369
|
+
const terminalState = turnStateFromTerminal(stringField(record.payload, "terminal") ?? record.payloadType.slice(13));
|
|
81370
|
+
state.terminal = terminalState;
|
|
81371
|
+
const drafts = [];
|
|
81372
|
+
const remainder = assistantTextRemainder(state.assistantText, stringField(record.payload, "text"));
|
|
81373
|
+
if (remainder) drafts.push(...appendAssistantText({
|
|
81374
|
+
text: remainder,
|
|
81375
|
+
state,
|
|
81376
|
+
context,
|
|
81377
|
+
record
|
|
81378
|
+
}));
|
|
81379
|
+
if (state.assistantItemStarted) drafts.push((stamp) => ({
|
|
81380
|
+
type: "item.completed",
|
|
81381
|
+
...stamp,
|
|
81382
|
+
...base(context),
|
|
81383
|
+
itemId: RuntimeItemId.make(context.assistantItemId),
|
|
81384
|
+
payload: {
|
|
81385
|
+
itemType: "assistant_message",
|
|
81386
|
+
status: "completed"
|
|
81387
|
+
}
|
|
81388
|
+
}));
|
|
81389
|
+
const reason = stringField(record.payload, "reason");
|
|
81390
|
+
drafts.push((stamp) => ({
|
|
81391
|
+
type: "turn.completed",
|
|
81392
|
+
...stamp,
|
|
81393
|
+
...base(context),
|
|
81394
|
+
payload: {
|
|
81395
|
+
state: terminalState,
|
|
81396
|
+
...reason ? { stopReason: reason } : {},
|
|
81397
|
+
...terminalState === "failed" && reason ? { errorMessage: reason } : {}
|
|
81398
|
+
},
|
|
81399
|
+
raw: rawFrom(record)
|
|
81400
|
+
}));
|
|
81401
|
+
return drafts;
|
|
81402
|
+
}
|
|
81403
|
+
function appendAssistantText(input) {
|
|
81404
|
+
const { text, state, context, record } = input;
|
|
81405
|
+
const drafts = [];
|
|
81406
|
+
if (!state.assistantItemStarted) {
|
|
81407
|
+
state.assistantItemStarted = true;
|
|
81408
|
+
drafts.push((stamp) => ({
|
|
81409
|
+
type: "item.started",
|
|
81410
|
+
...stamp,
|
|
81411
|
+
...base(context),
|
|
81412
|
+
itemId: RuntimeItemId.make(context.assistantItemId),
|
|
81413
|
+
payload: {
|
|
81414
|
+
itemType: "assistant_message",
|
|
81415
|
+
status: "inProgress"
|
|
81416
|
+
}
|
|
81417
|
+
}));
|
|
81418
|
+
}
|
|
81419
|
+
state.assistantText += text;
|
|
81420
|
+
drafts.push((stamp) => ({
|
|
81421
|
+
type: "content.delta",
|
|
81422
|
+
...stamp,
|
|
81423
|
+
...base(context),
|
|
81424
|
+
itemId: RuntimeItemId.make(context.assistantItemId),
|
|
81425
|
+
payload: {
|
|
81426
|
+
streamKind: "assistant_text",
|
|
81427
|
+
delta: text
|
|
81428
|
+
},
|
|
81429
|
+
raw: rawFrom(record)
|
|
81430
|
+
}));
|
|
81431
|
+
return drafts;
|
|
81432
|
+
}
|
|
81433
|
+
/**
|
|
81434
|
+
* The tail of `finalText` that was never streamed. Returns `undefined` when
|
|
81435
|
+
* the streamed text already covers it, or when the two diverge — a divergent
|
|
81436
|
+
* final text is dropped rather than duplicated into the transcript.
|
|
81437
|
+
*/
|
|
81438
|
+
function assistantTextRemainder(streamed, finalText) {
|
|
81439
|
+
if (finalText === void 0 || finalText.length === 0) return void 0;
|
|
81440
|
+
if (streamed.length === 0) return finalText;
|
|
81441
|
+
if (!finalText.startsWith(streamed)) return void 0;
|
|
81442
|
+
const remainder = finalText.slice(streamed.length);
|
|
81443
|
+
return remainder.length > 0 ? remainder : void 0;
|
|
81444
|
+
}
|
|
81445
|
+
function turnStateFromTerminal(terminal) {
|
|
81446
|
+
switch (terminal) {
|
|
81447
|
+
case "completed": return "completed";
|
|
81448
|
+
case "cancelled":
|
|
81449
|
+
case "canceled": return "cancelled";
|
|
81450
|
+
case "interrupted": return "interrupted";
|
|
81451
|
+
default: return "failed";
|
|
81452
|
+
}
|
|
81453
|
+
}
|
|
81454
|
+
/** `tool.write_file` → `write_file`; anything else is not a tool task. */
|
|
81455
|
+
function toolNameFromTaskKind(taskKind) {
|
|
81456
|
+
if (!taskKind || !taskKind.startsWith("tool.")) return void 0;
|
|
81457
|
+
const name = taskKind.slice(5).trim();
|
|
81458
|
+
return name.length > 0 ? name : void 0;
|
|
81459
|
+
}
|
|
81460
|
+
/** `tool:call_019f…` → `call_019f…`. */
|
|
81461
|
+
function toolCallIdFromIdempotencyKey(key) {
|
|
81462
|
+
if (!key || !key.startsWith("tool:")) return void 0;
|
|
81463
|
+
const callId = key.slice(5).trim();
|
|
81464
|
+
return callId.length > 0 ? callId : void 0;
|
|
81465
|
+
}
|
|
81466
|
+
function itemTypeForToolName(toolName) {
|
|
81467
|
+
switch (toolName) {
|
|
81468
|
+
case "bash":
|
|
81469
|
+
case "shell":
|
|
81470
|
+
case "run_command":
|
|
81471
|
+
case "unified_exec": return "command_execution";
|
|
81472
|
+
case "write_file":
|
|
81473
|
+
case "edit_file":
|
|
81474
|
+
case "multi_edit":
|
|
81475
|
+
case "apply_patch":
|
|
81476
|
+
case "delete_file":
|
|
81477
|
+
case "move_file": return "file_change";
|
|
81478
|
+
case "web_search":
|
|
81479
|
+
case "web_fetch": return "web_search";
|
|
81480
|
+
case "view_image": return "image_view";
|
|
81481
|
+
default:
|
|
81482
|
+
if (toolName?.startsWith("subagent_")) return "collab_agent_tool_call";
|
|
81483
|
+
if (toolName?.startsWith("mcp__")) return "mcp_tool_call";
|
|
81484
|
+
return "dynamic_tool_call";
|
|
81485
|
+
}
|
|
81486
|
+
}
|
|
81487
|
+
function base(context) {
|
|
81488
|
+
return {
|
|
81489
|
+
provider: context.provider,
|
|
81490
|
+
...context.providerInstanceId ? { providerInstanceId: context.providerInstanceId } : {},
|
|
81491
|
+
threadId: context.threadId,
|
|
81492
|
+
turnId: context.turnId
|
|
81493
|
+
};
|
|
81494
|
+
}
|
|
81495
|
+
function rawFrom(record) {
|
|
81496
|
+
return {
|
|
81497
|
+
source: "muse.exec.jsonl",
|
|
81498
|
+
method: record.payloadType,
|
|
81499
|
+
payload: record.payload
|
|
81500
|
+
};
|
|
81501
|
+
}
|
|
81502
|
+
function isRecord$1(value) {
|
|
81503
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
81504
|
+
}
|
|
81505
|
+
function stringField(source, key) {
|
|
81506
|
+
const value = source?.[key];
|
|
81507
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
81508
|
+
}
|
|
81509
|
+
function recordField(source, key) {
|
|
81510
|
+
const value = source?.[key];
|
|
81511
|
+
return isRecord$1(value) ? value : void 0;
|
|
81512
|
+
}
|
|
81513
|
+
function eventField(payload) {
|
|
81514
|
+
return recordField(payload, "event");
|
|
81515
|
+
}
|
|
81516
|
+
function truncate(value, max) {
|
|
81517
|
+
if (value === void 0) return void 0;
|
|
81518
|
+
const trimmed = value.trim();
|
|
81519
|
+
if (trimmed.length === 0) return void 0;
|
|
81520
|
+
return trimmed.length <= max ? trimmed : `${trimmed.slice(0, max)}…`;
|
|
81521
|
+
}
|
|
81522
|
+
//#endregion
|
|
81523
|
+
//#region src/textGeneration/MuseTextGeneration.ts
|
|
81524
|
+
/**
|
|
81525
|
+
* MuseTextGeneration — commit messages, PR text, branch names and thread
|
|
81526
|
+
* titles through Muse Code.
|
|
81527
|
+
*
|
|
81528
|
+
* Muse has no lightweight completion endpoint behind the CLI, so each request
|
|
81529
|
+
* is one headless `muse exec --json` run with the session log disabled: a
|
|
81530
|
+
* throwaway agent turn whose final text we parse as JSON. Reasoning effort is
|
|
81531
|
+
* pinned low because these are short structured-output tasks and Muse Spark
|
|
81532
|
+
* bills reasoning as output tokens.
|
|
81533
|
+
*
|
|
81534
|
+
* @module textGeneration/MuseTextGeneration
|
|
81535
|
+
*/
|
|
81536
|
+
const MUSE_TIMEOUT_MS = 18e4;
|
|
81537
|
+
const MUSE_TEXT_REASONING_EFFORT = "low";
|
|
81538
|
+
/** A structured-output turn should never need to loop; cap it cheaply. */
|
|
81539
|
+
const MUSE_TEXT_MAX_MODEL_STEPS = "8";
|
|
81540
|
+
const isTextGenerationError = Schema$1.is(TextGenerationError);
|
|
81541
|
+
/** Final assistant text from a `muse exec --json` stdout stream. */
|
|
81542
|
+
function museTerminalTextFromJsonl(stdout) {
|
|
81543
|
+
let terminalText;
|
|
81544
|
+
let streamed = "";
|
|
81545
|
+
for (const line of stdout.split("\n")) {
|
|
81546
|
+
const record = parseMuseExecLine(line);
|
|
81547
|
+
if (!record) continue;
|
|
81548
|
+
if (record.payloadType === "run.output.delta") {
|
|
81549
|
+
const delta = record.payload["text"];
|
|
81550
|
+
if (typeof delta === "string") streamed += delta;
|
|
81551
|
+
continue;
|
|
81552
|
+
}
|
|
81553
|
+
if (record.payloadType.startsWith("run.terminal.")) {
|
|
81554
|
+
const text = record.payload["text"];
|
|
81555
|
+
if (typeof text === "string" && text.length > 0) terminalText = text;
|
|
81556
|
+
}
|
|
81557
|
+
}
|
|
81558
|
+
const resolved = terminalText ?? streamed;
|
|
81559
|
+
return resolved.trim().length > 0 ? resolved : void 0;
|
|
81560
|
+
}
|
|
81561
|
+
const makeMuseTextGeneration = (museSettings, environment = process.env) => Effect.sync(() => {
|
|
81562
|
+
const runMuseJson = ({ operation, cwd, prompt, outputSchemaJson, modelSelection }) => Effect.gen(function* () {
|
|
81563
|
+
const binaryPath = museSettings.binaryPath || "muse";
|
|
81564
|
+
const spawnCommand = yield* resolveSpawnCommand(binaryPath, [
|
|
81565
|
+
"exec",
|
|
81566
|
+
"--json",
|
|
81567
|
+
"--no-session-log",
|
|
81568
|
+
"--reasoning-effort",
|
|
81569
|
+
MUSE_TEXT_REASONING_EFFORT,
|
|
81570
|
+
"--max-model-steps",
|
|
81571
|
+
MUSE_TEXT_MAX_MODEL_STEPS,
|
|
81572
|
+
"--disable-approval",
|
|
81573
|
+
"--disable-write",
|
|
81574
|
+
"--disable-shell",
|
|
81575
|
+
...modelSelection.model ? ["--model", modelSelection.model] : [],
|
|
81576
|
+
...museSettings.baseUrl ? ["--base-url", museSettings.baseUrl] : [],
|
|
81577
|
+
prompt
|
|
81578
|
+
], { env: environment });
|
|
81579
|
+
const result = yield* spawnAndCollect(binaryPath, ChildProcess.make(spawnCommand.command, spawnCommand.args, {
|
|
81580
|
+
cwd,
|
|
81581
|
+
env: environment,
|
|
81582
|
+
shell: spawnCommand.shell
|
|
81583
|
+
})).pipe(Effect.timeoutOption(MUSE_TIMEOUT_MS), Effect.flatMap(Option.match({
|
|
81584
|
+
onNone: () => Effect.fail(new TextGenerationError({
|
|
81585
|
+
operation,
|
|
81586
|
+
detail: "Muse Code request timed out."
|
|
81587
|
+
})),
|
|
81588
|
+
onSome: Effect.succeed
|
|
81589
|
+
})), Effect.mapError((cause) => isTextGenerationError(cause) ? cause : new TextGenerationError({
|
|
81590
|
+
operation,
|
|
81591
|
+
detail: "Muse Code request failed.",
|
|
81592
|
+
cause
|
|
81593
|
+
})));
|
|
81594
|
+
const output = museTerminalTextFromJsonl(result.stdout);
|
|
81595
|
+
if (!output) return yield* new TextGenerationError({
|
|
81596
|
+
operation,
|
|
81597
|
+
detail: result.code === 0 ? "Muse Code returned empty output." : `Muse Code exited with code ${result.code}.`
|
|
81598
|
+
});
|
|
81599
|
+
return yield* Schema$1.decodeEffect(Schema$1.fromJsonString(outputSchemaJson))(extractJsonObject(output)).pipe(Effect.catchTags({ SchemaError: (cause) => Effect.fail(new TextGenerationError({
|
|
81600
|
+
operation,
|
|
81601
|
+
detail: "Muse Code returned invalid structured output.",
|
|
81602
|
+
cause
|
|
81603
|
+
})) }));
|
|
81604
|
+
}).pipe(Effect.mapError((cause) => isTextGenerationError(cause) ? cause : new TextGenerationError({
|
|
81605
|
+
operation,
|
|
81606
|
+
detail: "Muse Code text generation failed.",
|
|
81607
|
+
cause
|
|
81608
|
+
})));
|
|
81609
|
+
return {
|
|
81610
|
+
generateCommitMessage: Effect.fn("MuseTextGeneration.generateCommitMessage")(function* (input) {
|
|
81611
|
+
const { prompt, outputSchema } = buildCommitMessagePrompt({
|
|
81612
|
+
branch: input.branch,
|
|
81613
|
+
stagedSummary: input.stagedSummary,
|
|
81614
|
+
stagedPatch: input.stagedPatch,
|
|
81615
|
+
includeBranch: input.includeBranch === true,
|
|
81616
|
+
policy: input.policy
|
|
81617
|
+
});
|
|
81618
|
+
const generated = yield* runMuseJson({
|
|
81619
|
+
operation: "generateCommitMessage",
|
|
81620
|
+
cwd: input.cwd,
|
|
81621
|
+
prompt,
|
|
81622
|
+
outputSchemaJson: outputSchema,
|
|
81623
|
+
modelSelection: input.modelSelection
|
|
81624
|
+
});
|
|
81625
|
+
return {
|
|
81626
|
+
subject: sanitizeCommitSubject(generated.subject),
|
|
81627
|
+
body: generated.body.trim(),
|
|
81628
|
+
..."branch" in generated && typeof generated.branch === "string" ? { branch: sanitizeFeatureBranchName(generated.branch) } : {}
|
|
81629
|
+
};
|
|
81630
|
+
}),
|
|
81631
|
+
generatePrContent: Effect.fn("MuseTextGeneration.generatePrContent")(function* (input) {
|
|
81632
|
+
const { prompt, outputSchema } = buildPrContentPrompt({
|
|
81633
|
+
baseBranch: input.baseBranch,
|
|
81634
|
+
headBranch: input.headBranch,
|
|
81635
|
+
commitSummary: input.commitSummary,
|
|
81636
|
+
diffSummary: input.diffSummary,
|
|
81637
|
+
diffPatch: input.diffPatch,
|
|
81638
|
+
policy: input.policy,
|
|
81639
|
+
changeRequestTemplate: input.changeRequestTemplate
|
|
81640
|
+
});
|
|
81641
|
+
const generated = yield* runMuseJson({
|
|
81642
|
+
operation: "generatePrContent",
|
|
81643
|
+
cwd: input.cwd,
|
|
81644
|
+
prompt,
|
|
81645
|
+
outputSchemaJson: outputSchema,
|
|
81646
|
+
modelSelection: input.modelSelection
|
|
81647
|
+
});
|
|
81648
|
+
return {
|
|
81649
|
+
title: sanitizePrTitle(generated.title),
|
|
81650
|
+
body: generated.body.trim()
|
|
81651
|
+
};
|
|
81652
|
+
}),
|
|
81653
|
+
generateBranchName: Effect.fn("MuseTextGeneration.generateBranchName")(function* (input) {
|
|
81654
|
+
const { prompt, outputSchema } = buildBranchNamePrompt({
|
|
81655
|
+
message: input.message,
|
|
81656
|
+
attachments: input.attachments
|
|
81657
|
+
});
|
|
81658
|
+
return { branch: sanitizeBranchFragment((yield* runMuseJson({
|
|
81659
|
+
operation: "generateBranchName",
|
|
81660
|
+
cwd: input.cwd,
|
|
81661
|
+
prompt,
|
|
81662
|
+
outputSchemaJson: outputSchema,
|
|
81663
|
+
modelSelection: input.modelSelection
|
|
81664
|
+
})).branch) };
|
|
81665
|
+
}),
|
|
81666
|
+
generateThreadTitle: Effect.fn("MuseTextGeneration.generateThreadTitle")(function* (input) {
|
|
81667
|
+
const { prompt, outputSchema } = buildThreadTitlePrompt({
|
|
81668
|
+
message: input.message,
|
|
81669
|
+
attachments: input.attachments
|
|
81670
|
+
});
|
|
81671
|
+
return { title: sanitizeThreadTitle((yield* runMuseJson({
|
|
81672
|
+
operation: "generateThreadTitle",
|
|
81673
|
+
cwd: input.cwd,
|
|
81674
|
+
prompt,
|
|
81675
|
+
outputSchemaJson: outputSchema,
|
|
81676
|
+
modelSelection: input.modelSelection
|
|
81677
|
+
})).title) };
|
|
81678
|
+
})
|
|
81679
|
+
};
|
|
81680
|
+
});
|
|
81681
|
+
//#endregion
|
|
81682
|
+
//#region src/provider/muse/MuseExecRuntime.ts
|
|
81683
|
+
/**
|
|
81684
|
+
* MuseExecRuntime — one `muse exec --json` child process per turn.
|
|
81685
|
+
*
|
|
81686
|
+
* Muse Code has no long-lived protocol surface: a turn is a process, and the
|
|
81687
|
+
* thread is rebuilt from the CLI's own event-sourced session log when the
|
|
81688
|
+
* next turn passes `--session-id`. This module owns spawning, line framing,
|
|
81689
|
+
* interruption, and exit classification; it knows nothing about canonical
|
|
81690
|
+
* runtime events.
|
|
81691
|
+
*
|
|
81692
|
+
* @module provider/muse/MuseExecRuntime
|
|
81693
|
+
*/
|
|
81694
|
+
/** Exit code Muse uses for a turn that failed or was cancelled. */
|
|
81695
|
+
const MUSE_EXIT_FAILED = 1;
|
|
81696
|
+
/** Exit codes produced by SIGINT / SIGTERM. */
|
|
81697
|
+
const MUSE_EXIT_SIGINT = 130;
|
|
81698
|
+
const MUSE_EXIT_SIGTERM = 143;
|
|
81699
|
+
/**
|
|
81700
|
+
* Spawn one turn. The child is bound to the caller's scope, so closing the
|
|
81701
|
+
* scope kills it; `awaitOutcome` is how a caller waits for a clean end.
|
|
81702
|
+
*/
|
|
81703
|
+
const runMuseExec = Effect.fn("runMuseExec")(function* (input) {
|
|
81704
|
+
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
81705
|
+
const runScope = yield* Scope.Scope;
|
|
81706
|
+
const spawnCommand = yield* resolveSpawnCommand(input.binaryPath, [...input.args], { env: input.environment }).pipe(Effect.mapError((cause) => new ProviderAdapterProcessError({
|
|
81707
|
+
provider: "muse",
|
|
81708
|
+
threadId: input.threadId,
|
|
81709
|
+
detail: `Failed to resolve the Muse Code binary (${input.binaryPath}).`,
|
|
81710
|
+
cause
|
|
81711
|
+
})));
|
|
81712
|
+
const child = yield* spawner.spawn(ChildProcess.make(spawnCommand.command, spawnCommand.args, {
|
|
81713
|
+
cwd: input.cwd,
|
|
81714
|
+
env: input.environment,
|
|
81715
|
+
shell: spawnCommand.shell
|
|
81716
|
+
})).pipe(Effect.provideService(Scope.Scope, runScope), Effect.mapError((cause) => new ProviderAdapterProcessError({
|
|
81717
|
+
provider: "muse",
|
|
81718
|
+
threadId: input.threadId,
|
|
81719
|
+
detail: "Failed to spawn `muse exec`.",
|
|
81720
|
+
cause
|
|
81721
|
+
})));
|
|
81722
|
+
const stderrRef = yield* Ref.make("");
|
|
81723
|
+
const interruptedRef = yield* Ref.make(false);
|
|
81724
|
+
const stdoutFiber = yield* child.stdout.pipe(Stream.decodeText(), Stream.splitLines, Stream.runForEach(input.onLine), Effect.ignore, Effect.forkIn(runScope));
|
|
81725
|
+
const stderrFiber = yield* child.stderr.pipe(Stream.decodeText(), Stream.runForEach((chunk) => Ref.update(stderrRef, (stderr) => `${stderr}${chunk}`.slice(-4e3))), Effect.ignore, Effect.forkIn(runScope));
|
|
81726
|
+
return {
|
|
81727
|
+
awaitOutcome: Effect.gen(function* () {
|
|
81728
|
+
const code = yield* child.exitCode.pipe(Effect.orElseSucceed(() => MUSE_EXIT_FAILED));
|
|
81729
|
+
yield* Fiber.await(stdoutFiber).pipe(Effect.ignore);
|
|
81730
|
+
yield* Fiber.await(stderrFiber).pipe(Effect.ignore);
|
|
81731
|
+
const exitCode = Number(code);
|
|
81732
|
+
const interrupted = yield* Ref.get(interruptedRef);
|
|
81733
|
+
if (exitCode === 0) return { kind: "completed" };
|
|
81734
|
+
if (interrupted || exitCode === MUSE_EXIT_SIGINT || exitCode === MUSE_EXIT_SIGTERM) return { kind: "interrupted" };
|
|
81735
|
+
return {
|
|
81736
|
+
kind: "failed",
|
|
81737
|
+
exitCode,
|
|
81738
|
+
stderr: (yield* Ref.get(stderrRef)).trim()
|
|
81739
|
+
};
|
|
81740
|
+
}),
|
|
81741
|
+
interrupt: Ref.set(interruptedRef, true).pipe(Effect.andThen(child.kill({
|
|
81742
|
+
killSignal: "SIGINT",
|
|
81743
|
+
forceKillAfter: "5 seconds"
|
|
81744
|
+
}).pipe(Effect.ignore)), Effect.asVoid)
|
|
81745
|
+
};
|
|
81746
|
+
});
|
|
81747
|
+
//#endregion
|
|
81748
|
+
//#region src/provider/muse/MuseSessionLog.ts
|
|
81749
|
+
/** Root directory holding Muse Code's per-session event logs. */
|
|
81750
|
+
const museDataRoot = Effect.fn("museDataRoot")(function* (environment = process.env) {
|
|
81751
|
+
const path = yield* Path.Path;
|
|
81752
|
+
const xdgDataHome = environment["XDG_DATA_HOME"]?.trim();
|
|
81753
|
+
const base = xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome : path.join(NodeOS.homedir(), ".local", "share");
|
|
81754
|
+
return path.join(base, "muse");
|
|
81755
|
+
});
|
|
81756
|
+
/**
|
|
81757
|
+
* Locate a session log by id. The CLI files logs under the date the session
|
|
81758
|
+
* was created, which we do not know for a resumed session, so the year /
|
|
81759
|
+
* month / day levels are walked. Returns `undefined` when the session has no
|
|
81760
|
+
* log yet (a `--no-session-log` run, or a run that died before its first
|
|
81761
|
+
* flush).
|
|
81762
|
+
*/
|
|
81763
|
+
const findMuseSessionLog = Effect.fn("findMuseSessionLog")(function* (input) {
|
|
81764
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
81765
|
+
const path = yield* Path.Path;
|
|
81766
|
+
const sessionsRoot = path.join(yield* museDataRoot(input.environment ?? process.env), "sessions");
|
|
81767
|
+
const listing = (directory) => fileSystem.readDirectory(directory).pipe(Effect.orElseSucceed(() => []));
|
|
81768
|
+
const descending = (entries) => [...entries].sort().reverse();
|
|
81769
|
+
for (const year of descending(yield* listing(sessionsRoot))) {
|
|
81770
|
+
const yearPath = path.join(sessionsRoot, year);
|
|
81771
|
+
for (const month of descending(yield* listing(yearPath))) {
|
|
81772
|
+
const monthPath = path.join(yearPath, month);
|
|
81773
|
+
for (const day of descending(yield* listing(monthPath))) {
|
|
81774
|
+
const candidate = path.join(monthPath, day, input.sessionId, "session.jsonl");
|
|
81775
|
+
if (yield* fileSystem.exists(candidate).pipe(Effect.orElseSucceed(() => false))) return candidate;
|
|
81776
|
+
}
|
|
81777
|
+
}
|
|
81778
|
+
}
|
|
81779
|
+
});
|
|
81780
|
+
/**
|
|
81781
|
+
* Sum the token usage recorded in a session log.
|
|
81782
|
+
*
|
|
81783
|
+
* Muse attributes usage per model call (`goal_usage_attribution`), including
|
|
81784
|
+
* the background observer agents, so the totals here cover everything the
|
|
81785
|
+
* session spent — which is what a user reading a token counter expects.
|
|
81786
|
+
*/
|
|
81787
|
+
function parseMuseTokenUsage(contents) {
|
|
81788
|
+
let total = {
|
|
81789
|
+
inputTokens: 0,
|
|
81790
|
+
outputTokens: 0,
|
|
81791
|
+
cachedTokens: 0,
|
|
81792
|
+
reasoningTokens: 0
|
|
81793
|
+
};
|
|
81794
|
+
let last;
|
|
81795
|
+
let seen = false;
|
|
81796
|
+
for (const line of contents.split("\n")) {
|
|
81797
|
+
const quantity = usageQuantityFromLine(line);
|
|
81798
|
+
if (!quantity) continue;
|
|
81799
|
+
seen = true;
|
|
81800
|
+
last = quantity;
|
|
81801
|
+
total = {
|
|
81802
|
+
inputTokens: total.inputTokens + quantity.inputTokens,
|
|
81803
|
+
outputTokens: total.outputTokens + quantity.outputTokens,
|
|
81804
|
+
cachedTokens: total.cachedTokens + quantity.cachedTokens,
|
|
81805
|
+
reasoningTokens: total.reasoningTokens + quantity.reasoningTokens
|
|
81806
|
+
};
|
|
81807
|
+
}
|
|
81808
|
+
if (!seen) return void 0;
|
|
81809
|
+
return {
|
|
81810
|
+
usedTokens: total.inputTokens + total.outputTokens,
|
|
81811
|
+
inputTokens: total.inputTokens,
|
|
81812
|
+
cachedInputTokens: total.cachedTokens,
|
|
81813
|
+
outputTokens: total.outputTokens,
|
|
81814
|
+
reasoningOutputTokens: total.reasoningTokens,
|
|
81815
|
+
...last ? {
|
|
81816
|
+
lastUsedTokens: last.inputTokens + last.outputTokens,
|
|
81817
|
+
lastInputTokens: last.inputTokens,
|
|
81818
|
+
lastCachedInputTokens: last.cachedTokens,
|
|
81819
|
+
lastOutputTokens: last.outputTokens,
|
|
81820
|
+
lastReasoningOutputTokens: last.reasoningTokens
|
|
81821
|
+
} : {},
|
|
81822
|
+
compactsAutomatically: true
|
|
81823
|
+
};
|
|
81824
|
+
}
|
|
81825
|
+
function usageQuantityFromLine(line) {
|
|
81826
|
+
const trimmed = line.trim();
|
|
81827
|
+
if (trimmed.length === 0 || !trimmed.includes("goal_usage_attribution")) return void 0;
|
|
81828
|
+
let decoded;
|
|
81829
|
+
try {
|
|
81830
|
+
decoded = JSON.parse(trimmed);
|
|
81831
|
+
} catch {
|
|
81832
|
+
return;
|
|
81833
|
+
}
|
|
81834
|
+
const quantity = readPath(decoded, [
|
|
81835
|
+
"payload",
|
|
81836
|
+
"event",
|
|
81837
|
+
"record",
|
|
81838
|
+
"quantity"
|
|
81839
|
+
]);
|
|
81840
|
+
if (!isRecord(quantity)) return void 0;
|
|
81841
|
+
return {
|
|
81842
|
+
inputTokens: nonNegativeInt(quantity["input_tokens"]),
|
|
81843
|
+
outputTokens: nonNegativeInt(quantity["output_tokens"]),
|
|
81844
|
+
cachedTokens: nonNegativeInt(quantity["cached_tokens"]),
|
|
81845
|
+
reasoningTokens: nonNegativeInt(quantity["reasoning_tokens"])
|
|
81846
|
+
};
|
|
81847
|
+
}
|
|
81848
|
+
/** Read a session's cumulative usage, or `undefined` when unavailable. */
|
|
81849
|
+
const readMuseSessionUsage = Effect.fn("readMuseSessionUsage")(function* (input) {
|
|
81850
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
81851
|
+
const logPath = yield* findMuseSessionLog(input);
|
|
81852
|
+
if (logPath === void 0) return void 0;
|
|
81853
|
+
const contents = yield* fileSystem.readFileString(logPath).pipe(Effect.orElseSucceed(() => void 0));
|
|
81854
|
+
return contents === void 0 ? void 0 : parseMuseTokenUsage(contents);
|
|
81855
|
+
});
|
|
81856
|
+
/**
|
|
81857
|
+
* Parse one `model-catalog/*.json` document. Hidden rows are dropped: the CLI
|
|
81858
|
+
* marks a row `visibility: "visible"` when it should appear in `/models`.
|
|
81859
|
+
*/
|
|
81860
|
+
function parseMuseModelCatalog(contents) {
|
|
81861
|
+
let decoded;
|
|
81862
|
+
try {
|
|
81863
|
+
decoded = JSON.parse(contents);
|
|
81864
|
+
} catch {
|
|
81865
|
+
return [];
|
|
81866
|
+
}
|
|
81867
|
+
const rows = isRecord(decoded) ? decoded["rows"] : void 0;
|
|
81868
|
+
if (!Array.isArray(rows)) return [];
|
|
81869
|
+
const models = [];
|
|
81870
|
+
for (const row of rows) {
|
|
81871
|
+
if (!isRecord(row)) continue;
|
|
81872
|
+
const slug = typeof row["model_id"] === "string" ? row["model_id"].trim() : "";
|
|
81873
|
+
if (slug.length === 0) continue;
|
|
81874
|
+
if (typeof row["visibility"] === "string" && row["visibility"] !== "visible") continue;
|
|
81875
|
+
const label = typeof row["display_label"] === "string" ? row["display_label"].trim() : "";
|
|
81876
|
+
const contextLimit = row["context_limit"];
|
|
81877
|
+
models.push({
|
|
81878
|
+
slug,
|
|
81879
|
+
name: label.length > 0 ? label : slug,
|
|
81880
|
+
contextLimit: typeof contextLimit === "number" && contextLimit > 0 ? contextLimit : void 0,
|
|
81881
|
+
isDefault: row["is_default"] === true
|
|
81882
|
+
});
|
|
81883
|
+
}
|
|
81884
|
+
return models;
|
|
81885
|
+
}
|
|
81886
|
+
/** Read every model row the CLI has cached on disk. */
|
|
81887
|
+
const readMuseModelCatalog = Effect.fn("readMuseModelCatalog")(function* (environment = process.env) {
|
|
81888
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
81889
|
+
const path = yield* Path.Path;
|
|
81890
|
+
const catalogRoot = path.join(yield* museDataRoot(environment), "model-catalog");
|
|
81891
|
+
const entries = yield* fileSystem.readDirectory(catalogRoot).pipe(Effect.orElseSucceed(() => []));
|
|
81892
|
+
const bySlug = /* @__PURE__ */ new Map();
|
|
81893
|
+
for (const entry of [...entries].sort()) {
|
|
81894
|
+
if (!entry.endsWith(".json")) continue;
|
|
81895
|
+
const contents = yield* fileSystem.readFileString(path.join(catalogRoot, entry)).pipe(Effect.orElseSucceed(() => void 0));
|
|
81896
|
+
if (contents === void 0) continue;
|
|
81897
|
+
for (const model of parseMuseModelCatalog(contents)) if (!bySlug.has(model.slug)) bySlug.set(model.slug, model);
|
|
81898
|
+
}
|
|
81899
|
+
return [...bySlug.values()];
|
|
81900
|
+
});
|
|
81901
|
+
function readPath(source, keys) {
|
|
81902
|
+
let current = source;
|
|
81903
|
+
for (const key of keys) {
|
|
81904
|
+
if (!isRecord(current)) return void 0;
|
|
81905
|
+
current = current[key];
|
|
81906
|
+
}
|
|
81907
|
+
return current;
|
|
81908
|
+
}
|
|
81909
|
+
function isRecord(value) {
|
|
81910
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
81911
|
+
}
|
|
81912
|
+
function nonNegativeInt(value) {
|
|
81913
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.trunc(value) : 0;
|
|
81914
|
+
}
|
|
81915
|
+
//#endregion
|
|
81916
|
+
//#region src/provider/Layers/MuseAdapter.ts
|
|
81917
|
+
/**
|
|
81918
|
+
* MuseAdapter — Meta Muse Code as a P4Code provider.
|
|
81919
|
+
*
|
|
81920
|
+
* Muse Code (beta, CLI 0.1.0) exposes no ACP or app-server protocol; the only
|
|
81921
|
+
* scriptable surface is `muse exec --json`, which runs one prompt to
|
|
81922
|
+
* completion and streams JSONL events on stdout. A P4Code thread therefore
|
|
81923
|
+
* maps onto a Muse *session id*: every turn spawns a fresh `muse exec` with
|
|
81924
|
+
* `--session-id`, and Muse replays its own event-sourced session log to
|
|
81925
|
+
* recover the conversation.
|
|
81926
|
+
*
|
|
81927
|
+
* Consequences that are visible to users, and deliberate:
|
|
81928
|
+
*
|
|
81929
|
+
* - **No interactive approvals.** Headless Muse has no channel to answer an
|
|
81930
|
+
* approval prompt, so the adapter runs with approval disabled and lets
|
|
81931
|
+
* Muse's OS sandbox do the containing. `respondToRequest` fails rather
|
|
81932
|
+
* than pretending to route a decision, and `approval-required` threads get
|
|
81933
|
+
* a `config.warning`.
|
|
81934
|
+
* - **No provider-side rollback.** Muse can fork a session interactively but
|
|
81935
|
+
* exposes nothing headless.
|
|
81936
|
+
* - **Tool arguments are not streamed.** They exist only in the on-disk
|
|
81937
|
+
* session log; items carry the tool name, its result text, and Muse's
|
|
81938
|
+
* `edit_facts`.
|
|
81939
|
+
*
|
|
81940
|
+
* @module provider/Layers/MuseAdapter
|
|
81941
|
+
*/
|
|
81942
|
+
const PROVIDER$1 = ProviderDriverKind.make("muse");
|
|
81943
|
+
const MUSE_RESUME_VERSION = 1;
|
|
81944
|
+
function museResumeCursor(museSessionId) {
|
|
81945
|
+
return {
|
|
81946
|
+
version: MUSE_RESUME_VERSION,
|
|
81947
|
+
sessionId: museSessionId
|
|
81948
|
+
};
|
|
81949
|
+
}
|
|
81950
|
+
/** Recover a Muse session id from a persisted resume cursor. */
|
|
81951
|
+
function parseMuseResume(raw) {
|
|
81952
|
+
if (typeof raw !== "object" || raw === null) return void 0;
|
|
81953
|
+
const candidate = raw;
|
|
81954
|
+
if (candidate.version !== MUSE_RESUME_VERSION) return void 0;
|
|
81955
|
+
return typeof candidate.sessionId === "string" && candidate.sessionId.length > 0 ? { sessionId: candidate.sessionId } : void 0;
|
|
81956
|
+
}
|
|
81957
|
+
function makeMuseAdapter(museSettings, options) {
|
|
81958
|
+
return Effect.gen(function* () {
|
|
81959
|
+
const boundInstanceId = options?.instanceId ?? ProviderInstanceId.make("muse");
|
|
81960
|
+
const environment = options?.environment ?? process.env;
|
|
81961
|
+
const crypto = yield* Crypto.Crypto;
|
|
81962
|
+
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
81963
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
81964
|
+
const path = yield* Path.Path;
|
|
81965
|
+
const serverConfig = yield* Effect.service(ServerConfig$1);
|
|
81966
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
81967
|
+
const runtimeEventPubSub = yield* PubSub.unbounded();
|
|
81968
|
+
const nowIso = Effect.map(DateTime.now, DateTime.formatIso);
|
|
81969
|
+
const randomUUIDv4 = crypto.randomUUIDv4.pipe(Effect.mapError((cause) => new ProviderAdapterRequestError({
|
|
81970
|
+
provider: PROVIDER$1,
|
|
81971
|
+
method: "crypto/randomUUIDv4",
|
|
81972
|
+
detail: "Failed to generate a Muse runtime identifier.",
|
|
81973
|
+
cause
|
|
81974
|
+
})));
|
|
81975
|
+
const makeEventStamp = () => Effect.all({
|
|
81976
|
+
eventId: Effect.map(randomUUIDv4, EventId.make),
|
|
81977
|
+
createdAt: nowIso
|
|
81978
|
+
});
|
|
81979
|
+
const publish = (event) => PubSub.publish(runtimeEventPubSub, event).pipe(Effect.asVoid);
|
|
81980
|
+
const requireSession = (threadId) => Effect.suspend(() => {
|
|
81981
|
+
const ctx = sessions.get(threadId);
|
|
81982
|
+
return ctx === void 0 || ctx.stopped ? Effect.fail(new ProviderAdapterSessionNotFoundError({
|
|
81983
|
+
provider: PROVIDER$1,
|
|
81984
|
+
threadId
|
|
81985
|
+
})) : Effect.succeed(ctx);
|
|
81986
|
+
});
|
|
81987
|
+
const startSession = (input) => Effect.gen(function* () {
|
|
81988
|
+
const existing = sessions.get(input.threadId);
|
|
81989
|
+
if (existing && !existing.stopped) return { ...existing.session };
|
|
81990
|
+
const resumed = parseMuseResume(input.resumeCursor);
|
|
81991
|
+
const museSessionId = resumed?.sessionId ?? (yield* randomUUIDv4);
|
|
81992
|
+
const cwd = input.cwd ?? process.cwd();
|
|
81993
|
+
const createdAt = yield* nowIso;
|
|
81994
|
+
const session = {
|
|
81995
|
+
provider: PROVIDER$1,
|
|
81996
|
+
providerInstanceId: boundInstanceId,
|
|
81997
|
+
status: "ready",
|
|
81998
|
+
runtimeMode: input.runtimeMode,
|
|
81999
|
+
cwd,
|
|
82000
|
+
...input.modelSelection?.model ? { model: input.modelSelection.model } : {},
|
|
82001
|
+
threadId: input.threadId,
|
|
82002
|
+
resumeCursor: museResumeCursor(museSessionId),
|
|
82003
|
+
createdAt,
|
|
82004
|
+
updatedAt: createdAt
|
|
82005
|
+
};
|
|
82006
|
+
const ctx = {
|
|
82007
|
+
threadId: input.threadId,
|
|
82008
|
+
museSessionId,
|
|
82009
|
+
cwd,
|
|
82010
|
+
session,
|
|
82011
|
+
activeTurn: void 0,
|
|
82012
|
+
turns: [],
|
|
82013
|
+
stopped: false
|
|
82014
|
+
};
|
|
82015
|
+
sessions.set(input.threadId, ctx);
|
|
82016
|
+
yield* publish({
|
|
82017
|
+
type: "session.started",
|
|
82018
|
+
...yield* makeEventStamp(),
|
|
82019
|
+
provider: PROVIDER$1,
|
|
82020
|
+
providerInstanceId: boundInstanceId,
|
|
82021
|
+
threadId: input.threadId,
|
|
82022
|
+
payload: resumed ? { resume: input.resumeCursor } : {}
|
|
82023
|
+
});
|
|
82024
|
+
yield* publish({
|
|
82025
|
+
type: "thread.started",
|
|
82026
|
+
...yield* makeEventStamp(),
|
|
82027
|
+
provider: PROVIDER$1,
|
|
82028
|
+
providerInstanceId: boundInstanceId,
|
|
82029
|
+
threadId: input.threadId,
|
|
82030
|
+
payload: { providerThreadId: museSessionId }
|
|
82031
|
+
});
|
|
82032
|
+
if (museApprovalsUnsupported(input.runtimeMode)) yield* publish({
|
|
82033
|
+
type: "config.warning",
|
|
82034
|
+
...yield* makeEventStamp(),
|
|
82035
|
+
provider: PROVIDER$1,
|
|
82036
|
+
providerInstanceId: boundInstanceId,
|
|
82037
|
+
threadId: input.threadId,
|
|
82038
|
+
payload: {
|
|
82039
|
+
summary: "Muse Code cannot ask for approvals in headless runs.",
|
|
82040
|
+
details: "This thread runs with approvals disabled and Muse's OS sandbox enabled; `muse exec` has no channel to answer an approval prompt."
|
|
82041
|
+
}
|
|
82042
|
+
});
|
|
82043
|
+
return { ...session };
|
|
82044
|
+
});
|
|
82045
|
+
const sendTurn = (input) => Effect.gen(function* () {
|
|
82046
|
+
const ctx = yield* requireSession(input.threadId);
|
|
82047
|
+
if (ctx.activeTurn) return yield* new ProviderAdapterRequestError({
|
|
82048
|
+
provider: PROVIDER$1,
|
|
82049
|
+
method: "muse/exec",
|
|
82050
|
+
detail: "A Muse turn is already running on this thread. `muse exec` runs one prompt per process, so turns cannot overlap."
|
|
82051
|
+
});
|
|
82052
|
+
const prompt = input.input?.trim();
|
|
82053
|
+
if (!prompt) return yield* new ProviderAdapterValidationError({
|
|
82054
|
+
provider: PROVIDER$1,
|
|
82055
|
+
operation: "sendTurn",
|
|
82056
|
+
issue: "Muse Code requires prompt text; attachments alone cannot start a turn."
|
|
82057
|
+
});
|
|
82058
|
+
const imagePaths = [];
|
|
82059
|
+
for (const attachment of input.attachments ?? []) {
|
|
82060
|
+
const attachmentPath = resolveAttachmentPath({
|
|
82061
|
+
attachmentsDir: serverConfig.attachmentsDir,
|
|
82062
|
+
attachment
|
|
82063
|
+
});
|
|
82064
|
+
if (!attachmentPath) return yield* new ProviderAdapterRequestError({
|
|
82065
|
+
provider: PROVIDER$1,
|
|
82066
|
+
method: "muse/exec",
|
|
82067
|
+
detail: `Invalid attachment id '${attachment.id}'.`
|
|
82068
|
+
});
|
|
82069
|
+
imagePaths.push(attachmentPath);
|
|
82070
|
+
}
|
|
82071
|
+
const turnId = TurnId.make(yield* randomUUIDv4);
|
|
82072
|
+
const model = input.modelSelection?.model ?? ctx.session.model;
|
|
82073
|
+
const args = buildMuseExecArgs({
|
|
82074
|
+
sessionId: ctx.museSessionId,
|
|
82075
|
+
prompt,
|
|
82076
|
+
model,
|
|
82077
|
+
baseUrl: museSettings.baseUrl || void 0,
|
|
82078
|
+
runtimeMode: ctx.session.runtimeMode,
|
|
82079
|
+
imagePaths
|
|
82080
|
+
});
|
|
82081
|
+
const state = makeMuseExecTurnState();
|
|
82082
|
+
const mappingContext = {
|
|
82083
|
+
provider: PROVIDER$1,
|
|
82084
|
+
providerInstanceId: boundInstanceId,
|
|
82085
|
+
threadId: input.threadId,
|
|
82086
|
+
turnId,
|
|
82087
|
+
assistantItemId: `${turnId}:assistant`
|
|
82088
|
+
};
|
|
82089
|
+
const handleLine = (line) => Effect.gen(function* () {
|
|
82090
|
+
const record = parseMuseExecLine(line);
|
|
82091
|
+
if (!record) return;
|
|
82092
|
+
const drafts = mapMuseExecRecord({
|
|
82093
|
+
record,
|
|
82094
|
+
state,
|
|
82095
|
+
context: mappingContext
|
|
82096
|
+
});
|
|
82097
|
+
for (const draft of drafts) yield* publish(draft(yield* makeEventStamp()));
|
|
82098
|
+
}).pipe(Effect.orElseSucceed(() => void 0));
|
|
82099
|
+
ctx.turns.push({
|
|
82100
|
+
id: turnId,
|
|
82101
|
+
items: []
|
|
82102
|
+
});
|
|
82103
|
+
ctx.session = {
|
|
82104
|
+
...ctx.session,
|
|
82105
|
+
status: "running",
|
|
82106
|
+
activeTurnId: turnId,
|
|
82107
|
+
updatedAt: yield* nowIso,
|
|
82108
|
+
...model ? { model } : {}
|
|
82109
|
+
};
|
|
82110
|
+
const turnScope = yield* Scope.make();
|
|
82111
|
+
const run = yield* runMuseExec({
|
|
82112
|
+
threadId: input.threadId,
|
|
82113
|
+
binaryPath: museSettings.binaryPath || "muse",
|
|
82114
|
+
args,
|
|
82115
|
+
cwd: ctx.cwd,
|
|
82116
|
+
environment,
|
|
82117
|
+
onLine: handleLine
|
|
82118
|
+
}).pipe(Effect.provideService(Scope.Scope, turnScope), Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), Effect.tapError(() => Scope.close(turnScope, Exit.void)));
|
|
82119
|
+
ctx.activeTurn = {
|
|
82120
|
+
turnId,
|
|
82121
|
+
run,
|
|
82122
|
+
state
|
|
82123
|
+
};
|
|
82124
|
+
const outcome = yield* run.awaitOutcome;
|
|
82125
|
+
yield* Scope.close(turnScope, Exit.void);
|
|
82126
|
+
ctx.activeTurn = void 0;
|
|
82127
|
+
if (state.terminal === void 0) if (outcome.kind === "interrupted") yield* publish({
|
|
82128
|
+
type: "turn.aborted",
|
|
82129
|
+
...yield* makeEventStamp(),
|
|
82130
|
+
provider: PROVIDER$1,
|
|
82131
|
+
providerInstanceId: boundInstanceId,
|
|
82132
|
+
threadId: input.threadId,
|
|
82133
|
+
turnId,
|
|
82134
|
+
payload: { reason: "interrupted" }
|
|
82135
|
+
});
|
|
82136
|
+
else {
|
|
82137
|
+
const detail = outcome.kind === "failed" ? outcome.stderr || `\`muse exec\` exited with code ${outcome.exitCode}.` : "`muse exec` ended without a terminal event.";
|
|
82138
|
+
yield* publish({
|
|
82139
|
+
type: "turn.completed",
|
|
82140
|
+
...yield* makeEventStamp(),
|
|
82141
|
+
provider: PROVIDER$1,
|
|
82142
|
+
providerInstanceId: boundInstanceId,
|
|
82143
|
+
threadId: input.threadId,
|
|
82144
|
+
turnId,
|
|
82145
|
+
payload: {
|
|
82146
|
+
state: "failed",
|
|
82147
|
+
errorMessage: detail
|
|
82148
|
+
}
|
|
82149
|
+
});
|
|
82150
|
+
}
|
|
82151
|
+
yield* publishTokenUsage(ctx, turnId);
|
|
82152
|
+
const updatedAt = yield* nowIso;
|
|
82153
|
+
const { activeTurnId: _activeTurnId, ...readySession } = ctx.session;
|
|
82154
|
+
ctx.session = {
|
|
82155
|
+
...readySession,
|
|
82156
|
+
status: "ready",
|
|
82157
|
+
updatedAt
|
|
82158
|
+
};
|
|
82159
|
+
return {
|
|
82160
|
+
threadId: input.threadId,
|
|
82161
|
+
turnId,
|
|
82162
|
+
resumeCursor: museResumeCursor(ctx.museSessionId)
|
|
82163
|
+
};
|
|
82164
|
+
});
|
|
82165
|
+
/**
|
|
82166
|
+
* Token usage never reaches stdout; it is written to the session log. One
|
|
82167
|
+
* read after the turn keeps the counter honest without tailing the file.
|
|
82168
|
+
*/
|
|
82169
|
+
const publishTokenUsage = (ctx, turnId) => Effect.gen(function* () {
|
|
82170
|
+
const usage = yield* readMuseSessionUsage({
|
|
82171
|
+
sessionId: ctx.museSessionId,
|
|
82172
|
+
environment
|
|
82173
|
+
}).pipe(Effect.provideService(FileSystem.FileSystem, fileSystem), Effect.provideService(Path.Path, path), Effect.orElseSucceed(() => void 0));
|
|
82174
|
+
if (!usage) return;
|
|
82175
|
+
yield* publish({
|
|
82176
|
+
type: "thread.token-usage.updated",
|
|
82177
|
+
...yield* makeEventStamp(),
|
|
82178
|
+
provider: PROVIDER$1,
|
|
82179
|
+
providerInstanceId: boundInstanceId,
|
|
82180
|
+
threadId: ctx.threadId,
|
|
82181
|
+
turnId,
|
|
82182
|
+
payload: { usage }
|
|
82183
|
+
});
|
|
82184
|
+
}).pipe(Effect.orElseSucceed(() => void 0));
|
|
82185
|
+
const interruptTurn = (threadId, turnId) => Effect.gen(function* () {
|
|
82186
|
+
const active = (yield* requireSession(threadId)).activeTurn;
|
|
82187
|
+
if (!active) return;
|
|
82188
|
+
if (turnId !== void 0 && turnId !== active.turnId) return;
|
|
82189
|
+
yield* active.run.interrupt;
|
|
82190
|
+
});
|
|
82191
|
+
const respondToRequest = (threadId) => Effect.gen(function* () {
|
|
82192
|
+
yield* requireSession(threadId);
|
|
82193
|
+
return yield* new ProviderAdapterRequestError({
|
|
82194
|
+
provider: PROVIDER$1,
|
|
82195
|
+
method: "muse/approval",
|
|
82196
|
+
detail: "Muse Code has no approval channel in headless runs, so it never opens an approval request."
|
|
82197
|
+
});
|
|
82198
|
+
});
|
|
82199
|
+
const respondToUserInput = (threadId) => Effect.gen(function* () {
|
|
82200
|
+
yield* requireSession(threadId);
|
|
82201
|
+
return yield* new ProviderAdapterRequestError({
|
|
82202
|
+
provider: PROVIDER$1,
|
|
82203
|
+
method: "muse/user-input",
|
|
82204
|
+
detail: "Muse Code does not ask structured questions in headless runs."
|
|
82205
|
+
});
|
|
82206
|
+
});
|
|
82207
|
+
const readThread = (threadId) => Effect.gen(function* () {
|
|
82208
|
+
return {
|
|
82209
|
+
threadId,
|
|
82210
|
+
turns: (yield* requireSession(threadId)).turns
|
|
82211
|
+
};
|
|
82212
|
+
});
|
|
82213
|
+
const rollbackThread = (threadId, numTurns) => Effect.gen(function* () {
|
|
82214
|
+
yield* requireSession(threadId);
|
|
82215
|
+
if (!Number.isInteger(numTurns) || numTurns < 1) return yield* new ProviderAdapterValidationError({
|
|
82216
|
+
provider: PROVIDER$1,
|
|
82217
|
+
operation: "rollbackThread",
|
|
82218
|
+
issue: "numTurns must be an integer >= 1."
|
|
82219
|
+
});
|
|
82220
|
+
return yield* new ProviderAdapterRequestError({
|
|
82221
|
+
provider: PROVIDER$1,
|
|
82222
|
+
method: "muse/rollback",
|
|
82223
|
+
detail: "Muse Code exposes no headless rollback for a session."
|
|
82224
|
+
});
|
|
82225
|
+
});
|
|
82226
|
+
const stopSessionInternal = (ctx) => Effect.gen(function* () {
|
|
82227
|
+
if (ctx.stopped) return;
|
|
82228
|
+
ctx.stopped = true;
|
|
82229
|
+
if (ctx.activeTurn) {
|
|
82230
|
+
yield* ctx.activeTurn.run.interrupt.pipe(Effect.ignore);
|
|
82231
|
+
ctx.activeTurn = void 0;
|
|
82232
|
+
}
|
|
82233
|
+
const updatedAt = yield* nowIso;
|
|
82234
|
+
ctx.session = {
|
|
82235
|
+
...ctx.session,
|
|
82236
|
+
status: "closed",
|
|
82237
|
+
updatedAt
|
|
82238
|
+
};
|
|
82239
|
+
sessions.delete(ctx.threadId);
|
|
82240
|
+
yield* publish({
|
|
82241
|
+
type: "session.exited",
|
|
82242
|
+
...yield* makeEventStamp(),
|
|
82243
|
+
provider: PROVIDER$1,
|
|
82244
|
+
providerInstanceId: boundInstanceId,
|
|
82245
|
+
threadId: ctx.threadId,
|
|
82246
|
+
payload: {
|
|
82247
|
+
reason: "stopped",
|
|
82248
|
+
exitKind: "graceful"
|
|
82249
|
+
}
|
|
82250
|
+
});
|
|
82251
|
+
});
|
|
82252
|
+
const stopSession = (threadId) => Effect.flatMap(requireSession(threadId), stopSessionInternal);
|
|
82253
|
+
const listSessions = () => Effect.sync(() => Array.from(sessions.values(), (ctx) => ({ ...ctx.session })));
|
|
82254
|
+
const hasSession = (threadId) => Effect.sync(() => {
|
|
82255
|
+
const ctx = sessions.get(threadId);
|
|
82256
|
+
return ctx !== void 0 && !ctx.stopped;
|
|
82257
|
+
});
|
|
82258
|
+
const stopAll = () => Effect.forEach(Array.from(sessions.values()), stopSessionInternal, { discard: true });
|
|
82259
|
+
yield* Effect.addFinalizer(() => Effect.ignore(stopAll()).pipe(Effect.tap(() => PubSub.shutdown(runtimeEventPubSub))));
|
|
82260
|
+
return {
|
|
82261
|
+
provider: PROVIDER$1,
|
|
82262
|
+
capabilities: { sessionModelSwitch: "in-session" },
|
|
82263
|
+
startSession,
|
|
82264
|
+
sendTurn,
|
|
82265
|
+
interruptTurn,
|
|
82266
|
+
readThread,
|
|
82267
|
+
rollbackThread,
|
|
82268
|
+
respondToRequest,
|
|
82269
|
+
respondToUserInput,
|
|
82270
|
+
stopSession,
|
|
82271
|
+
listSessions,
|
|
82272
|
+
hasSession,
|
|
82273
|
+
stopAll,
|
|
82274
|
+
streamEvents: Stream.fromPubSub(runtimeEventPubSub)
|
|
82275
|
+
};
|
|
82276
|
+
});
|
|
82277
|
+
}
|
|
82278
|
+
//#endregion
|
|
82279
|
+
//#region src/provider/Layers/MuseProvider.ts
|
|
82280
|
+
const MUSE_PRESENTATION = {
|
|
82281
|
+
displayName: "Muse Code",
|
|
82282
|
+
badgeLabel: "Early Access",
|
|
82283
|
+
showInteractionModeToggle: false,
|
|
82284
|
+
requiresNewThreadForModelChange: false,
|
|
82285
|
+
supportedRuntimeModes: ["auto", "full-access"]
|
|
82286
|
+
};
|
|
82287
|
+
const EMPTY_CAPABILITIES = createModelCapabilities({ optionDescriptors: [] });
|
|
82288
|
+
const VERSION_PROBE_TIMEOUT_MS = 4e3;
|
|
82289
|
+
/** Models Meta documents for Muse Code; used until the CLI caches a catalog. */
|
|
82290
|
+
const MUSE_BUILT_IN_MODELS = [{
|
|
82291
|
+
slug: "muse-spark-1.2",
|
|
82292
|
+
name: "Muse Spark 1.2",
|
|
82293
|
+
isCustom: false,
|
|
82294
|
+
capabilities: EMPTY_CAPABILITIES
|
|
82295
|
+
}, {
|
|
82296
|
+
slug: "muse-spark-1.2-contributor",
|
|
82297
|
+
name: "Muse Spark 1.2 (contributor)",
|
|
82298
|
+
isCustom: false,
|
|
82299
|
+
isDefault: true,
|
|
82300
|
+
capabilities: EMPTY_CAPABILITIES
|
|
82301
|
+
}];
|
|
82302
|
+
function museModelsFromSettings(customModels, builtInModels = MUSE_BUILT_IN_MODELS) {
|
|
82303
|
+
return providerModelsFromSettings(builtInModels, customModels ?? [], EMPTY_CAPABILITIES);
|
|
82304
|
+
}
|
|
82305
|
+
const discoverMuseModels = Effect.fn("discoverMuseModels")(function* (environment) {
|
|
82306
|
+
return (yield* readMuseModelCatalog(environment)).map((model) => ({
|
|
82307
|
+
slug: model.slug,
|
|
82308
|
+
name: model.name,
|
|
82309
|
+
isCustom: false,
|
|
82310
|
+
...model.isDefault ? { isDefault: true } : {},
|
|
82311
|
+
capabilities: EMPTY_CAPABILITIES
|
|
82312
|
+
}));
|
|
82313
|
+
});
|
|
82314
|
+
/**
|
|
82315
|
+
* What P4Code can tell about Muse credentials without running the CLI.
|
|
82316
|
+
*
|
|
82317
|
+
* `META_API_KEY` takes priority inside Muse itself, then a stored key or
|
|
82318
|
+
* browser session in `~/.config/muse/auth.json`. Neither says whether the
|
|
82319
|
+
* credential is still valid, so a present credential reports
|
|
82320
|
+
* `authenticated` with the source as its label and a missing one reports
|
|
82321
|
+
* `unauthenticated`.
|
|
82322
|
+
*/
|
|
82323
|
+
const checkMuseAuth = Effect.fn("checkMuseAuth")(function* (environment) {
|
|
82324
|
+
if (environment["META_API_KEY"]?.trim()) return {
|
|
82325
|
+
status: "authenticated",
|
|
82326
|
+
type: "api-key",
|
|
82327
|
+
label: "META_API_KEY"
|
|
82328
|
+
};
|
|
82329
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
82330
|
+
const path = yield* Path.Path;
|
|
82331
|
+
const configHome = environment["XDG_CONFIG_HOME"]?.trim();
|
|
82332
|
+
const authPath = path.join(configHome && configHome.length > 0 ? configHome : path.join(NodeOS.homedir(), ".config"), "muse", "auth.json");
|
|
82333
|
+
return (yield* fileSystem.exists(authPath).pipe(Effect.orElseSucceed(() => false))) ? {
|
|
82334
|
+
status: "authenticated",
|
|
82335
|
+
type: "cli",
|
|
82336
|
+
label: "muse login"
|
|
82337
|
+
} : { status: "unauthenticated" };
|
|
82338
|
+
});
|
|
82339
|
+
function buildInitialMuseProviderSnapshot(museSettings) {
|
|
82340
|
+
return Effect.gen(function* () {
|
|
82341
|
+
const checkedAt = yield* Effect.map(DateTime.now, DateTime.formatIso);
|
|
82342
|
+
const models = museModelsFromSettings(museSettings.customModels);
|
|
82343
|
+
return buildServerProvider({
|
|
82344
|
+
presentation: MUSE_PRESENTATION,
|
|
82345
|
+
enabled: museSettings.enabled,
|
|
82346
|
+
checkedAt,
|
|
82347
|
+
models,
|
|
82348
|
+
probe: museSettings.enabled ? {
|
|
82349
|
+
installed: true,
|
|
82350
|
+
version: null,
|
|
82351
|
+
status: "warning",
|
|
82352
|
+
auth: { status: "unknown" },
|
|
82353
|
+
message: "Checking Muse Code CLI availability..."
|
|
82354
|
+
} : {
|
|
82355
|
+
installed: false,
|
|
82356
|
+
version: null,
|
|
82357
|
+
status: "warning",
|
|
82358
|
+
auth: { status: "unknown" },
|
|
82359
|
+
message: "Muse Code is disabled in P4Code settings."
|
|
82360
|
+
}
|
|
82361
|
+
});
|
|
82362
|
+
});
|
|
82363
|
+
}
|
|
82364
|
+
const runMuseVersionCommand = (museSettings, environment) => Effect.gen(function* () {
|
|
82365
|
+
const command = museSettings.binaryPath || "muse";
|
|
82366
|
+
const spawnCommand = yield* resolveSpawnCommand(command, [...MUSE_VERSION_ARGS], { env: environment });
|
|
82367
|
+
return yield* spawnAndCollect(command, ChildProcess.make(spawnCommand.command, spawnCommand.args, {
|
|
82368
|
+
env: environment,
|
|
82369
|
+
shell: spawnCommand.shell
|
|
82370
|
+
}));
|
|
82371
|
+
});
|
|
82372
|
+
const checkMuseProviderStatus = Effect.fn("checkMuseProviderStatus")(function* (museSettings, environment = process.env) {
|
|
82373
|
+
const checkedAt = DateTime.formatIso(yield* DateTime.now);
|
|
82374
|
+
const fallbackModels = museModelsFromSettings(museSettings.customModels);
|
|
82375
|
+
if (!museSettings.enabled) return buildServerProvider({
|
|
82376
|
+
presentation: MUSE_PRESENTATION,
|
|
82377
|
+
enabled: false,
|
|
82378
|
+
checkedAt,
|
|
82379
|
+
models: fallbackModels,
|
|
82380
|
+
probe: {
|
|
82381
|
+
installed: false,
|
|
82382
|
+
version: null,
|
|
82383
|
+
status: "warning",
|
|
82384
|
+
auth: { status: "unknown" },
|
|
82385
|
+
message: "Muse Code is disabled in P4Code settings."
|
|
82386
|
+
}
|
|
82387
|
+
});
|
|
82388
|
+
const versionResult = yield* runMuseVersionCommand(museSettings, environment).pipe(Effect.timeoutOption(VERSION_PROBE_TIMEOUT_MS), Effect.result);
|
|
82389
|
+
if (Result.isFailure(versionResult)) {
|
|
82390
|
+
const error = versionResult.failure;
|
|
82391
|
+
const missing = isCommandMissingCause(error);
|
|
82392
|
+
yield* (missing ? Effect.logDebug : Effect.logWarning)("Muse Code CLI health check failed.", { errorTag: error._tag });
|
|
82393
|
+
return buildServerProvider({
|
|
82394
|
+
presentation: MUSE_PRESENTATION,
|
|
82395
|
+
enabled: true,
|
|
82396
|
+
checkedAt,
|
|
82397
|
+
models: fallbackModels,
|
|
82398
|
+
probe: {
|
|
82399
|
+
installed: !missing,
|
|
82400
|
+
version: null,
|
|
82401
|
+
status: "error",
|
|
82402
|
+
auth: { status: "unknown" },
|
|
82403
|
+
message: missing ? "Muse Code CLI (`muse`) is not installed or not on PATH. Install it with `curl -fsSL https://dev.meta.ai/install.sh | sh`." : "Failed to execute the Muse Code CLI health check."
|
|
82404
|
+
}
|
|
82405
|
+
});
|
|
82406
|
+
}
|
|
82407
|
+
if (Option.isNone(versionResult.success)) return buildServerProvider({
|
|
82408
|
+
presentation: MUSE_PRESENTATION,
|
|
82409
|
+
enabled: true,
|
|
82410
|
+
checkedAt,
|
|
82411
|
+
models: fallbackModels,
|
|
82412
|
+
probe: {
|
|
82413
|
+
installed: true,
|
|
82414
|
+
version: null,
|
|
82415
|
+
status: "error",
|
|
82416
|
+
auth: { status: "unknown" },
|
|
82417
|
+
message: "Muse Code CLI is installed but timed out while running `muse --version`."
|
|
82418
|
+
}
|
|
82419
|
+
});
|
|
82420
|
+
const versionOutput = versionResult.success.value;
|
|
82421
|
+
const version = parseGenericCliVersion(`${versionOutput.stdout}\n${versionOutput.stderr}`);
|
|
82422
|
+
const auth = yield* checkMuseAuth(environment);
|
|
82423
|
+
if (versionOutput.code !== 0) {
|
|
82424
|
+
yield* Effect.logWarning("Muse Code CLI version probe exited with a non-zero status.", {
|
|
82425
|
+
exitCode: versionOutput.code,
|
|
82426
|
+
stdoutLength: versionOutput.stdout.length,
|
|
82427
|
+
stderrLength: versionOutput.stderr.length
|
|
82428
|
+
});
|
|
82429
|
+
return buildServerProvider({
|
|
82430
|
+
presentation: MUSE_PRESENTATION,
|
|
82431
|
+
enabled: true,
|
|
82432
|
+
checkedAt,
|
|
82433
|
+
models: fallbackModels,
|
|
82434
|
+
probe: {
|
|
82435
|
+
installed: true,
|
|
82436
|
+
version,
|
|
82437
|
+
status: "error",
|
|
82438
|
+
auth,
|
|
82439
|
+
message: "Muse Code CLI is installed but failed to run."
|
|
82440
|
+
}
|
|
82441
|
+
});
|
|
82442
|
+
}
|
|
82443
|
+
const discovered = yield* discoverMuseModels(environment);
|
|
82444
|
+
const models = discovered.length > 0 ? museModelsFromSettings(museSettings.customModels, discovered) : fallbackModels;
|
|
82445
|
+
if (auth.status !== "authenticated") return buildServerProvider({
|
|
82446
|
+
presentation: MUSE_PRESENTATION,
|
|
82447
|
+
enabled: true,
|
|
82448
|
+
checkedAt,
|
|
82449
|
+
models,
|
|
82450
|
+
probe: {
|
|
82451
|
+
installed: true,
|
|
82452
|
+
version,
|
|
82453
|
+
status: "warning",
|
|
82454
|
+
auth,
|
|
82455
|
+
message: "Muse Code is installed but not signed in. Run `muse login`, or set META_API_KEY."
|
|
82456
|
+
}
|
|
82457
|
+
});
|
|
82458
|
+
return buildServerProvider({
|
|
82459
|
+
presentation: MUSE_PRESENTATION,
|
|
82460
|
+
enabled: true,
|
|
82461
|
+
checkedAt,
|
|
82462
|
+
models,
|
|
82463
|
+
probe: {
|
|
82464
|
+
installed: true,
|
|
82465
|
+
version,
|
|
82466
|
+
status: "ready",
|
|
82467
|
+
auth
|
|
82468
|
+
}
|
|
82469
|
+
});
|
|
82470
|
+
});
|
|
82471
|
+
const enrichMuseSnapshot = (input) => enrichProviderSnapshotWithVersionAdvisory(input.snapshot, input.maintenanceCapabilities, { enableProviderUpdateChecks: input.enableProviderUpdateChecks }).pipe(Effect.provideService(HttpClient.HttpClient, input.httpClient), Effect.flatMap((enrichedSnapshot) => input.publishSnapshot(enrichedSnapshot)), Effect.catchCause((cause) => Effect.logWarning("Muse version advisory enrichment failed", { errorTag: causeErrorTag(cause) })), Effect.asVoid);
|
|
82472
|
+
//#endregion
|
|
82473
|
+
//#region src/provider/Drivers/MuseDriver.ts
|
|
82474
|
+
/**
|
|
82475
|
+
* MuseDriver — first-party driver for Meta's Muse Code CLI.
|
|
82476
|
+
*
|
|
82477
|
+
* @module provider/Drivers/MuseDriver
|
|
82478
|
+
*/
|
|
82479
|
+
const decodeMuseSettings = Schema$1.decodeSync(MuseSettings);
|
|
82480
|
+
const DRIVER_KIND$1 = ProviderDriverKind.make("muse");
|
|
82481
|
+
const SNAPSHOT_REFRESH_INTERVAL$1 = Duration.minutes(5);
|
|
82482
|
+
const UPDATE$1 = makeStaticProviderMaintenanceResolver(makeManualOnlyProviderMaintenanceCapabilities({
|
|
82483
|
+
provider: DRIVER_KIND$1,
|
|
82484
|
+
packageName: null
|
|
82485
|
+
}));
|
|
82486
|
+
const withInstanceIdentity$1 = (input) => (snapshot) => ({
|
|
82487
|
+
...snapshot,
|
|
82488
|
+
instanceId: input.instanceId,
|
|
82489
|
+
driver: DRIVER_KIND$1,
|
|
82490
|
+
...input.displayName ? { displayName: input.displayName } : {},
|
|
82491
|
+
...input.accentColor ? { accentColor: input.accentColor } : {},
|
|
82492
|
+
continuation: { groupKey: input.continuationGroupKey }
|
|
82493
|
+
});
|
|
82494
|
+
const MuseDriver = {
|
|
82495
|
+
driverKind: DRIVER_KIND$1,
|
|
82496
|
+
metadata: {
|
|
82497
|
+
displayName: "Muse Code",
|
|
82498
|
+
supportsMultipleInstances: true
|
|
82499
|
+
},
|
|
82500
|
+
configSchema: MuseSettings,
|
|
82501
|
+
defaultConfig: () => decodeMuseSettings({}),
|
|
82502
|
+
create: ({ instanceId, displayName, accentColor, environment, enabled, config }) => Effect.gen(function* () {
|
|
82503
|
+
const httpClient = yield* HttpClient.HttpClient;
|
|
82504
|
+
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
82505
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
82506
|
+
const path = yield* Path.Path;
|
|
82507
|
+
const serverSettings = yield* ServerSettingsService;
|
|
82508
|
+
const processEnv = mergeProviderInstanceEnvironment(environment);
|
|
82509
|
+
const continuationIdentity = defaultProviderContinuationIdentity({
|
|
82510
|
+
driverKind: DRIVER_KIND$1,
|
|
82511
|
+
instanceId
|
|
82512
|
+
});
|
|
82513
|
+
const stampIdentity = withInstanceIdentity$1({
|
|
82514
|
+
instanceId,
|
|
82515
|
+
displayName,
|
|
82516
|
+
accentColor,
|
|
82517
|
+
continuationGroupKey: continuationIdentity.continuationKey
|
|
82518
|
+
});
|
|
82519
|
+
const effectiveConfig = {
|
|
82520
|
+
...config,
|
|
82521
|
+
enabled
|
|
82522
|
+
};
|
|
82523
|
+
const maintenanceCapabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(UPDATE$1, {
|
|
82524
|
+
binaryPath: effectiveConfig.binaryPath,
|
|
82525
|
+
env: processEnv
|
|
82526
|
+
});
|
|
82527
|
+
const adapter = yield* makeMuseAdapter(effectiveConfig, {
|
|
82528
|
+
environment: processEnv,
|
|
82529
|
+
instanceId
|
|
82530
|
+
});
|
|
82531
|
+
const textGeneration = yield* makeMuseTextGeneration(effectiveConfig, processEnv);
|
|
82532
|
+
const snapshotSettings = makeProviderSnapshotSettingsSource(effectiveConfig, serverSettings);
|
|
82533
|
+
const snapshot = yield* makeManagedServerProvider({
|
|
82534
|
+
maintenanceCapabilities,
|
|
82535
|
+
getSettings: snapshotSettings.getSettings,
|
|
82536
|
+
streamSettings: snapshotSettings.streamSettings,
|
|
82537
|
+
haveSettingsChanged: haveProviderSnapshotSettingsChanged,
|
|
82538
|
+
initialSnapshot: (settings) => buildInitialMuseProviderSnapshot(settings.provider).pipe(Effect.map(stampIdentity)),
|
|
82539
|
+
checkProvider: checkMuseProviderStatus(effectiveConfig, processEnv).pipe(Effect.map(stampIdentity), Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), Effect.provideService(FileSystem.FileSystem, fileSystem), Effect.provideService(Path.Path, path)),
|
|
82540
|
+
enrichSnapshot: ({ settings, snapshot: currentSnapshot, publishSnapshot }) => enrichMuseSnapshot({
|
|
82541
|
+
snapshot: currentSnapshot,
|
|
82542
|
+
maintenanceCapabilities,
|
|
82543
|
+
enableProviderUpdateChecks: settings.enableProviderUpdateChecks,
|
|
82544
|
+
publishSnapshot,
|
|
82545
|
+
httpClient
|
|
82546
|
+
}),
|
|
81014
82547
|
refreshInterval: SNAPSHOT_REFRESH_INTERVAL$1
|
|
81015
82548
|
}).pipe(Effect.mapError((cause) => new ProviderDriverError({
|
|
81016
82549
|
driver: DRIVER_KIND$1,
|
|
81017
82550
|
instanceId,
|
|
81018
|
-
detail: `Failed to build
|
|
82551
|
+
detail: `Failed to build Muse snapshot: ${cause.message ?? String(cause)}`,
|
|
81019
82552
|
cause
|
|
81020
82553
|
})));
|
|
81021
82554
|
return {
|
|
@@ -82701,6 +84234,7 @@ const BUILT_IN_DRIVERS = [
|
|
|
82701
84234
|
ClaudeDriver,
|
|
82702
84235
|
CursorDriver,
|
|
82703
84236
|
GrokDriver,
|
|
84237
|
+
MuseDriver,
|
|
82704
84238
|
{
|
|
82705
84239
|
driverKind: DRIVER_KIND,
|
|
82706
84240
|
metadata: {
|
|
@@ -84147,7 +85681,9 @@ function runtimeEventToActivities(event, taskTitle) {
|
|
|
84147
85681
|
payload: {
|
|
84148
85682
|
taskId: event.payload.taskId,
|
|
84149
85683
|
...event.payload.taskType ? { taskType: event.payload.taskType } : {},
|
|
84150
|
-
...event.payload.description ? { detail: truncateDetail(event.payload.description) } : {}
|
|
85684
|
+
...event.payload.description ? { detail: truncateDetail(event.payload.description) } : {},
|
|
85685
|
+
...event.payload.toolUseId ? { toolUseId: event.payload.toolUseId } : {},
|
|
85686
|
+
...event.payload.subagentType ? { subagentType: event.payload.subagentType } : {}
|
|
84151
85687
|
},
|
|
84152
85688
|
turnId: toTurnId$1(event.turnId) ?? null,
|
|
84153
85689
|
...maybeSequence
|
|
@@ -84164,7 +85700,9 @@ function runtimeEventToActivities(event, taskTitle) {
|
|
|
84164
85700
|
detail: truncateDetail(event.payload.summary ?? event.payload.description),
|
|
84165
85701
|
...event.payload.summary ? { summary: truncateDetail(event.payload.summary) } : {},
|
|
84166
85702
|
...event.payload.lastToolName ? { lastToolName: event.payload.lastToolName } : {},
|
|
84167
|
-
...event.payload.usage !== void 0 ? { usage: event.payload.usage } : {}
|
|
85703
|
+
...event.payload.usage !== void 0 ? { usage: event.payload.usage } : {},
|
|
85704
|
+
...event.payload.toolUseId ? { toolUseId: event.payload.toolUseId } : {},
|
|
85705
|
+
...event.payload.subagentType ? { subagentType: event.payload.subagentType } : {}
|
|
84168
85706
|
},
|
|
84169
85707
|
turnId: toTurnId$1(event.turnId) ?? null,
|
|
84170
85708
|
...maybeSequence
|
|
@@ -84183,7 +85721,8 @@ function runtimeEventToActivities(event, taskTitle) {
|
|
|
84183
85721
|
summary: truncateDetail(event.payload.summary),
|
|
84184
85722
|
detail: truncateDetail(event.payload.summary)
|
|
84185
85723
|
} : {},
|
|
84186
|
-
...event.payload.usage !== void 0 ? { usage: event.payload.usage } : {}
|
|
85724
|
+
...event.payload.usage !== void 0 ? { usage: event.payload.usage } : {},
|
|
85725
|
+
...event.payload.toolUseId ? { toolUseId: event.payload.toolUseId } : {}
|
|
84187
85726
|
},
|
|
84188
85727
|
turnId: toTurnId$1(event.turnId) ?? null,
|
|
84189
85728
|
...maybeSequence
|