@alas-ide/codex-acp 2.6.0-alas.1 → 2.6.0-alas.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +136 -86
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -36335,6 +36335,109 @@ function hasOnlyKeys(value, allowed) {
|
|
|
36335
36335
|
return Object.keys(value).every((key) => allowedKeys.has(key));
|
|
36336
36336
|
}
|
|
36337
36337
|
|
|
36338
|
+
// src/PromptSuggestionGenerator.ts
|
|
36339
|
+
var PROMPT_SUGGESTIONS_META_KEY = "promptSuggestions";
|
|
36340
|
+
var SUGGESTION_EFFORT = "high";
|
|
36341
|
+
var SUGGESTION_SCHEMA = {
|
|
36342
|
+
type: "object",
|
|
36343
|
+
properties: { suggestion: { type: ["string", "null"] } },
|
|
36344
|
+
required: ["suggestion"],
|
|
36345
|
+
additionalProperties: false
|
|
36346
|
+
};
|
|
36347
|
+
var SUGGESTION_PROMPT = "This is an app-generated request for a suggested next user message. The user did not write this message.\n\nYour suggestion will appear in the user's empty message composer. They can accept it, edit it, or ignore it; it will not be sent automatically.\n\nPredict the single message this user is most likely to type next from the visible conversation. Use the whole conversation to understand their current intent and the latest exchange. Choose the action and specific object that best continue that intent, rather than a generally useful follow-up. Express its core naturally in the user's voice, keeping the requirements needed to retain its meaning. Choose the strongest grounded move even if several continuations are possible; uncertainty about exact wording or incidental details is not a reason to return null. Use null only when the conversation offers no grounded next move at all.\n\nSet suggestion to exactly one natural user message, one line, at most 240 characters, or null. No alternatives or explanation.\n\nReturn only JSON matching this schema: " + JSON.stringify(SUGGESTION_SCHEMA);
|
|
36348
|
+
function promptSuggestionsEnabled(env = process.env) {
|
|
36349
|
+
return env["CODEX_ACP_PROMPT_SUGGESTIONS"]?.trim().toLowerCase() !== "false";
|
|
36350
|
+
}
|
|
36351
|
+
function promptSuggestionsMeta(text, requestId) {
|
|
36352
|
+
return {
|
|
36353
|
+
[PROMPT_SUGGESTIONS_META_KEY]: {
|
|
36354
|
+
suggestions: text === null ? [] : [{ text }],
|
|
36355
|
+
...requestId !== void 0 ? { id: requestId } : {}
|
|
36356
|
+
}
|
|
36357
|
+
};
|
|
36358
|
+
}
|
|
36359
|
+
function promptSuggestionsRequestId(meta3) {
|
|
36360
|
+
if (meta3 === null || typeof meta3 !== "object") return void 0;
|
|
36361
|
+
const value = meta3[PROMPT_SUGGESTIONS_META_KEY];
|
|
36362
|
+
if (value === null || typeof value !== "object") return void 0;
|
|
36363
|
+
const id = value["id"];
|
|
36364
|
+
return typeof id === "string" && id.length > 0 && id.length <= 256 ? id : void 0;
|
|
36365
|
+
}
|
|
36366
|
+
var PromptSuggestionGenerator = class {
|
|
36367
|
+
constructor(client, publish) {
|
|
36368
|
+
this.client = client;
|
|
36369
|
+
this.publish = publish;
|
|
36370
|
+
}
|
|
36371
|
+
client;
|
|
36372
|
+
publish;
|
|
36373
|
+
generation = 0;
|
|
36374
|
+
lastPublished = null;
|
|
36375
|
+
/**
|
|
36376
|
+
* Fire-and-forget hook, called after a turn ends normally. A newer turn or {@link invalidate} drops its result.
|
|
36377
|
+
* With a `requestId` the result always goes out with it, an empty list when the sample gives nothing or fails,
|
|
36378
|
+
* so a client-neutral client waiting for that id can stop.
|
|
36379
|
+
*/
|
|
36380
|
+
onTurnCompleted(threadId, turnId, requestId) {
|
|
36381
|
+
const generation = ++this.generation;
|
|
36382
|
+
this.generateAndPublish(generation, threadId, turnId, requestId).catch(async () => {
|
|
36383
|
+
if (requestId === void 0 || generation !== this.generation) return;
|
|
36384
|
+
await this.publishAnswer(null, requestId).catch(() => {
|
|
36385
|
+
});
|
|
36386
|
+
});
|
|
36387
|
+
}
|
|
36388
|
+
/** A new prompt started or the session closed: a result still being generated is dropped. */
|
|
36389
|
+
invalidate() {
|
|
36390
|
+
this.generation++;
|
|
36391
|
+
}
|
|
36392
|
+
/**
|
|
36393
|
+
* Drops a result in flight and clears the suggestion the client holds. Returns `null` when nothing is held,
|
|
36394
|
+
* so the caller does not wait a tick for nothing.
|
|
36395
|
+
*/
|
|
36396
|
+
clear() {
|
|
36397
|
+
this.invalidate();
|
|
36398
|
+
if (this.lastPublished === null) return null;
|
|
36399
|
+
return this.publishIfChanged(null).catch(() => {
|
|
36400
|
+
});
|
|
36401
|
+
}
|
|
36402
|
+
/** The app-server restarted: later generations go to `client`. A generation in flight ends with the old one. */
|
|
36403
|
+
rebindAppServer(client) {
|
|
36404
|
+
this.client = client;
|
|
36405
|
+
}
|
|
36406
|
+
async generateAndPublish(generation, threadId, turnId, requestId) {
|
|
36407
|
+
const client = this.client;
|
|
36408
|
+
const response = await client.threadSample({
|
|
36409
|
+
threadId,
|
|
36410
|
+
expectedTurnId: turnId,
|
|
36411
|
+
prompt: SUGGESTION_PROMPT,
|
|
36412
|
+
effort: SUGGESTION_EFFORT
|
|
36413
|
+
});
|
|
36414
|
+
if (generation !== this.generation) return;
|
|
36415
|
+
const text = parseSuggestion(response.text);
|
|
36416
|
+
if (requestId !== void 0) await this.publishAnswer(text, requestId);
|
|
36417
|
+
else await this.publishIfChanged(text);
|
|
36418
|
+
}
|
|
36419
|
+
/** Answers a client-neutral request: it goes out even when it repeats the text the client holds. */
|
|
36420
|
+
async publishAnswer(text, requestId) {
|
|
36421
|
+
this.lastPublished = text;
|
|
36422
|
+
await this.publish(text, requestId);
|
|
36423
|
+
}
|
|
36424
|
+
async publishIfChanged(text) {
|
|
36425
|
+
if (text === this.lastPublished) return;
|
|
36426
|
+
this.lastPublished = text;
|
|
36427
|
+
await this.publish(text);
|
|
36428
|
+
}
|
|
36429
|
+
};
|
|
36430
|
+
function parseSuggestion(text) {
|
|
36431
|
+
if (!text?.trim()) return null;
|
|
36432
|
+
try {
|
|
36433
|
+
const value = JSON.parse(text).suggestion;
|
|
36434
|
+
if (typeof value !== "string") return null;
|
|
36435
|
+
return value.trim() || null;
|
|
36436
|
+
} catch {
|
|
36437
|
+
return null;
|
|
36438
|
+
}
|
|
36439
|
+
}
|
|
36440
|
+
|
|
36338
36441
|
// src/tool-calls/ClientCapabilities.ts
|
|
36339
36442
|
var ClientCapabilities = class _ClientCapabilities {
|
|
36340
36443
|
static DEFAULT = new _ClientCapabilities({
|
|
@@ -36353,7 +36456,8 @@ var ClientCapabilities = class _ClientCapabilities {
|
|
|
36353
36456
|
neutralPermissionPresentation: false,
|
|
36354
36457
|
neutralQuestionCustomAnswer: false,
|
|
36355
36458
|
neutralRecommendedConfigValue: false,
|
|
36356
|
-
neutralCommandPresentation: false
|
|
36459
|
+
neutralCommandPresentation: false,
|
|
36460
|
+
neutralPromptSuggestions: false
|
|
36357
36461
|
});
|
|
36358
36462
|
/** The client declares `_meta.jetbrains.air`. */
|
|
36359
36463
|
airClient;
|
|
@@ -36383,6 +36487,11 @@ var ClientCapabilities = class _ClientCapabilities {
|
|
|
36383
36487
|
neutralRecommendedConfigValue;
|
|
36384
36488
|
/** Available commands carry `_meta.commandPresentation`. Only ACP v1 reads the opt-in. */
|
|
36385
36489
|
neutralCommandPresentation;
|
|
36490
|
+
/**
|
|
36491
|
+
* A prompt that names `_meta.promptSuggestions.id` gets the predicted follow-up prompt of its turn.
|
|
36492
|
+
* Only ACP v1 reads the opt-in.
|
|
36493
|
+
*/
|
|
36494
|
+
neutralPromptSuggestions;
|
|
36386
36495
|
constructor(values) {
|
|
36387
36496
|
this.airClient = values.airClient;
|
|
36388
36497
|
this.airToolCallContract = values.airToolCallContract;
|
|
@@ -36400,6 +36509,11 @@ var ClientCapabilities = class _ClientCapabilities {
|
|
|
36400
36509
|
this.neutralQuestionCustomAnswer = values.neutralQuestionCustomAnswer;
|
|
36401
36510
|
this.neutralRecommendedConfigValue = values.neutralRecommendedConfigValue;
|
|
36402
36511
|
this.neutralCommandPresentation = values.neutralCommandPresentation;
|
|
36512
|
+
this.neutralPromptSuggestions = values.neutralPromptSuggestions;
|
|
36513
|
+
}
|
|
36514
|
+
/** Whether the client reads predicted follow-up prompts, in any form. */
|
|
36515
|
+
get predictsPrompts() {
|
|
36516
|
+
return this.airClient || this.neutralPromptSuggestions;
|
|
36403
36517
|
}
|
|
36404
36518
|
static from(capabilities) {
|
|
36405
36519
|
const airClient = isAirClient(capabilities);
|
|
@@ -36428,7 +36542,8 @@ var ClientCapabilities = class _ClientCapabilities {
|
|
|
36428
36542
|
neutralPermissionPresentation: clientRequestsNeutralPresentation(capabilities, NEUTRAL_PERMISSION_PRESENTATION_META_KEY),
|
|
36429
36543
|
neutralQuestionCustomAnswer: clientRequestsNeutralPresentation(capabilities, NEUTRAL_QUESTION_CUSTOM_ANSWER_META_KEY),
|
|
36430
36544
|
neutralRecommendedConfigValue: clientRequestsNeutralPresentation(capabilities, NEUTRAL_RECOMMENDED_CONFIG_VALUE_META_KEY),
|
|
36431
|
-
neutralCommandPresentation: clientRequestsNeutralPresentation(capabilities, NEUTRAL_COMMAND_PRESENTATION_META_KEY)
|
|
36545
|
+
neutralCommandPresentation: clientRequestsNeutralPresentation(capabilities, NEUTRAL_COMMAND_PRESENTATION_META_KEY),
|
|
36546
|
+
neutralPromptSuggestions: clientRequestsNeutralPresentation(capabilities, PROMPT_SUGGESTIONS_META_KEY)
|
|
36432
36547
|
});
|
|
36433
36548
|
}
|
|
36434
36549
|
/**
|
|
@@ -36459,7 +36574,8 @@ var ClientCapabilities = class _ClientCapabilities {
|
|
|
36459
36574
|
neutralPermissionPresentation: false,
|
|
36460
36575
|
neutralQuestionCustomAnswer: false,
|
|
36461
36576
|
neutralRecommendedConfigValue: false,
|
|
36462
|
-
neutralCommandPresentation: false
|
|
36577
|
+
neutralCommandPresentation: false,
|
|
36578
|
+
neutralPromptSuggestions: false
|
|
36463
36579
|
});
|
|
36464
36580
|
}
|
|
36465
36581
|
/**
|
|
@@ -42151,7 +42267,7 @@ var package_default = {
|
|
|
42151
42267
|
publishConfig: {
|
|
42152
42268
|
access: "public"
|
|
42153
42269
|
},
|
|
42154
|
-
version: "2.6.0-alas.
|
|
42270
|
+
version: "2.6.0-alas.2",
|
|
42155
42271
|
description: "",
|
|
42156
42272
|
main: "dist/index.js",
|
|
42157
42273
|
bin: {
|
|
@@ -42229,7 +42345,7 @@ var package_default = {
|
|
|
42229
42345
|
alasDownstream: {
|
|
42230
42346
|
upstreamVersion: "2.6.0",
|
|
42231
42347
|
upstreamCommit: "f3208913693bd4d5171d6c6b9be5ec1ff96c6431",
|
|
42232
|
-
sourceCommit: "
|
|
42348
|
+
sourceCommit: "e8e45a368d0d1f832fbd5307e1c08e879d1c9de3"
|
|
42233
42349
|
}
|
|
42234
42350
|
};
|
|
42235
42351
|
|
|
@@ -50759,83 +50875,6 @@ function titleSource(text) {
|
|
|
50759
50875
|
return text.slice(0, end);
|
|
50760
50876
|
}
|
|
50761
50877
|
|
|
50762
|
-
// src/PromptSuggestionGenerator.ts
|
|
50763
|
-
var PROMPT_SUGGESTIONS_META_KEY = "promptSuggestions";
|
|
50764
|
-
var SUGGESTION_EFFORT = "high";
|
|
50765
|
-
var SUGGESTION_SCHEMA = {
|
|
50766
|
-
type: "object",
|
|
50767
|
-
properties: { suggestion: { type: ["string", "null"] } },
|
|
50768
|
-
required: ["suggestion"],
|
|
50769
|
-
additionalProperties: false
|
|
50770
|
-
};
|
|
50771
|
-
var SUGGESTION_PROMPT = "This is an app-generated request for a suggested next user message. The user did not write this message.\n\nYour suggestion will appear in the user's empty message composer. They can accept it, edit it, or ignore it; it will not be sent automatically.\n\nPredict the single message this user is most likely to type next from the visible conversation. Use the whole conversation to understand their current intent and the latest exchange. Choose the action and specific object that best continue that intent, rather than a generally useful follow-up. Express its core naturally in the user's voice, keeping the requirements needed to retain its meaning. Choose the strongest grounded move even if several continuations are possible; uncertainty about exact wording or incidental details is not a reason to return null. Use null only when the conversation offers no grounded next move at all.\n\nSet suggestion to exactly one natural user message, one line, at most 240 characters, or null. No alternatives or explanation.\n\nReturn only JSON matching this schema: " + JSON.stringify(SUGGESTION_SCHEMA);
|
|
50772
|
-
function promptSuggestionsEnabled(env = process.env) {
|
|
50773
|
-
return env["CODEX_ACP_PROMPT_SUGGESTIONS"]?.trim().toLowerCase() !== "false";
|
|
50774
|
-
}
|
|
50775
|
-
function promptSuggestionsMeta(text) {
|
|
50776
|
-
return { [PROMPT_SUGGESTIONS_META_KEY]: { suggestions: text === null ? [] : [{ text }] } };
|
|
50777
|
-
}
|
|
50778
|
-
var PromptSuggestionGenerator = class {
|
|
50779
|
-
constructor(client, publish) {
|
|
50780
|
-
this.client = client;
|
|
50781
|
-
this.publish = publish;
|
|
50782
|
-
}
|
|
50783
|
-
client;
|
|
50784
|
-
publish;
|
|
50785
|
-
generation = 0;
|
|
50786
|
-
lastPublished = null;
|
|
50787
|
-
/** Fire-and-forget hook, called after a turn ends normally. A newer turn or {@link invalidate} drops its result. */
|
|
50788
|
-
onTurnCompleted(threadId, turnId) {
|
|
50789
|
-
const generation = ++this.generation;
|
|
50790
|
-
this.generateAndPublish(generation, threadId, turnId).catch(() => {
|
|
50791
|
-
});
|
|
50792
|
-
}
|
|
50793
|
-
/** A new prompt started or the session closed: a result still being generated is dropped. */
|
|
50794
|
-
invalidate() {
|
|
50795
|
-
this.generation++;
|
|
50796
|
-
}
|
|
50797
|
-
/**
|
|
50798
|
-
* Drops a result in flight and clears the suggestion the client holds. Returns `null` when nothing is held,
|
|
50799
|
-
* so the caller does not wait a tick for nothing.
|
|
50800
|
-
*/
|
|
50801
|
-
clear() {
|
|
50802
|
-
this.invalidate();
|
|
50803
|
-
if (this.lastPublished === null) return null;
|
|
50804
|
-
return this.publishIfChanged(null).catch(() => {
|
|
50805
|
-
});
|
|
50806
|
-
}
|
|
50807
|
-
/** The app-server restarted: later generations go to `client`. A generation in flight ends with the old one. */
|
|
50808
|
-
rebindAppServer(client) {
|
|
50809
|
-
this.client = client;
|
|
50810
|
-
}
|
|
50811
|
-
async generateAndPublish(generation, threadId, turnId) {
|
|
50812
|
-
const client = this.client;
|
|
50813
|
-
const response = await client.threadSample({
|
|
50814
|
-
threadId,
|
|
50815
|
-
expectedTurnId: turnId,
|
|
50816
|
-
prompt: SUGGESTION_PROMPT,
|
|
50817
|
-
effort: SUGGESTION_EFFORT
|
|
50818
|
-
});
|
|
50819
|
-
if (generation !== this.generation) return;
|
|
50820
|
-
await this.publishIfChanged(parseSuggestion(response.text));
|
|
50821
|
-
}
|
|
50822
|
-
async publishIfChanged(text) {
|
|
50823
|
-
if (text === this.lastPublished) return;
|
|
50824
|
-
this.lastPublished = text;
|
|
50825
|
-
await this.publish(text);
|
|
50826
|
-
}
|
|
50827
|
-
};
|
|
50828
|
-
function parseSuggestion(text) {
|
|
50829
|
-
if (!text?.trim()) return null;
|
|
50830
|
-
try {
|
|
50831
|
-
const value = JSON.parse(text).suggestion;
|
|
50832
|
-
if (typeof value !== "string") return null;
|
|
50833
|
-
return value.trim() || null;
|
|
50834
|
-
} catch {
|
|
50835
|
-
return null;
|
|
50836
|
-
}
|
|
50837
|
-
}
|
|
50838
|
-
|
|
50839
50878
|
// src/SessionIndex.ts
|
|
50840
50879
|
var AIR_SESSION_INDEX_KEY = "sessionIndex";
|
|
50841
50880
|
var AIR_SESSION_BATCH_GET_KEY = "sessionBatchGet";
|
|
@@ -53901,6 +53940,10 @@ var CodexAcpServer = class {
|
|
|
53901
53940
|
...this.capabilities.neutralCommandPresentation ? {
|
|
53902
53941
|
[NEUTRAL_COMMAND_PRESENTATION_META_KEY]: neutralPresentationCapability()
|
|
53903
53942
|
} : {},
|
|
53943
|
+
// Only while the adapter predicts at all: `CODEX_ACP_PROMPT_SUGGESTIONS=false` turns it off.
|
|
53944
|
+
...this.capabilities.neutralPromptSuggestions && promptSuggestionsEnabled() ? {
|
|
53945
|
+
[PROMPT_SUGGESTIONS_META_KEY]: neutralPresentationCapability()
|
|
53946
|
+
} : {},
|
|
53904
53947
|
// The session index for a client that opted in without AIR, see `docs/air-extensions.md`.
|
|
53905
53948
|
...neutralSessionIndex ? {
|
|
53906
53949
|
[NEUTRAL_SESSION_INDEX_META_KEY]: neutralSessionIndex
|
|
@@ -56673,13 +56716,13 @@ You have been logged out. Please try again.`);
|
|
|
56673
56716
|
return null;
|
|
56674
56717
|
}
|
|
56675
56718
|
createPromptSuggestions(sessionState) {
|
|
56676
|
-
if (!sessionState.clientCapabilities.
|
|
56719
|
+
if (!sessionState.clientCapabilities.predictsPrompts || !promptSuggestionsEnabled()) return void 0;
|
|
56677
56720
|
return new PromptSuggestionGenerator(
|
|
56678
56721
|
this.codexAcpClient.appServerClient,
|
|
56679
|
-
async (text) => {
|
|
56722
|
+
async (text, requestId) => {
|
|
56680
56723
|
await new ACPSessionConnection(this.connection, sessionState.sessionId).update({
|
|
56681
56724
|
sessionUpdate: "session_info_update",
|
|
56682
|
-
_meta: promptSuggestionsMeta(text)
|
|
56725
|
+
_meta: promptSuggestionsMeta(text, requestId)
|
|
56683
56726
|
});
|
|
56684
56727
|
}
|
|
56685
56728
|
);
|
|
@@ -57863,7 +57906,14 @@ You have been logged out. Please try again.`);
|
|
|
57863
57906
|
);
|
|
57864
57907
|
const promptText = params.prompt.filter((b) => b.type === "text").map((b) => b.text).join(" ").trim();
|
|
57865
57908
|
sessionState.titleGen?.onTurnCompleted(promptText);
|
|
57866
|
-
|
|
57909
|
+
const promptSuggestionRequestId = sessionState.clientCapabilities.neutralPromptSuggestions ? promptSuggestionsRequestId(params._meta) : void 0;
|
|
57910
|
+
if (turnCompleted.turn.status === "completed" && sessionState.collaborationMode !== PLAN_COLLABORATION_MODE && (sessionState.clientCapabilities.airClient || promptSuggestionRequestId !== void 0)) {
|
|
57911
|
+
sessionState.promptSuggestions?.onTurnCompleted(
|
|
57912
|
+
sessionState.sessionId,
|
|
57913
|
+
turnCompleted.turn.id,
|
|
57914
|
+
promptSuggestionRequestId
|
|
57915
|
+
);
|
|
57916
|
+
}
|
|
57867
57917
|
if (pendingInsertion === void 0) {
|
|
57868
57918
|
await this.publishFallbackSessionTitle(
|
|
57869
57919
|
sessionState,
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "2.6.0-alas.
|
|
6
|
+
"version": "2.6.0-alas.2",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"bin": {
|
|
@@ -81,6 +81,6 @@
|
|
|
81
81
|
"alasDownstream": {
|
|
82
82
|
"upstreamVersion": "2.6.0",
|
|
83
83
|
"upstreamCommit": "f3208913693bd4d5171d6c6b9be5ec1ff96c6431",
|
|
84
|
-
"sourceCommit": "
|
|
84
|
+
"sourceCommit": "e8e45a368d0d1f832fbd5307e1c08e879d1c9de3"
|
|
85
85
|
}
|
|
86
86
|
}
|