diff --git a/packages/provider-pi/src/server/adapter.test.ts b/packages/provider-pi/src/server/adapter.test.ts index dcc9023c2b95..484a44ef86a1 100644 --- a/packages/provider-pi/src/server/adapter.test.ts +++ b/packages/provider-pi/src/server/adapter.test.ts @@ -3080,6 +3080,40 @@ describe("PiAdapterV2", () => { }).pipe(Effect.scoped, Effect.provide(layerTest)), ); + it.effect("asks an input dialog's title when its placeholder is blank", () => + Effect.gen(function* () { + const fake = yield* makeFakePi; + const { runtime, takeEvent } = yield* openRuntime(fake); + yield* runtime.ensureThread({ + threadId: THREAD_ID, + modelSelection: modelSelection("default"), + runtimePolicy, + }); + const title = "Which database?\n1. Postgres\n2. Type something.\nType your answer:"; + yield* fake.emit({ + type: "extension_ui_request", + id: "ui-input", + method: "input", + title, + placeholder: "", + }); + const event = yield* takeEvent( + (event) => + event.type === "turn_item.updated" && event.turnItem.type === "user_input_request", + ); + if (event.type !== "turn_item.updated" || event.turnItem.type !== "user_input_request") { + return assert.fail("expected a user input request"); + } + assert.equal(decodeUserInputQuestions(event.turnItem.questions)[0]?.question, title); + yield* runtime.respondToRuntimeRequest({ + requestId: event.turnItem.requestId, + answers: { "ui-input": "SQLite" }, + }); + const response = yield* fake.takeRequest("extension_ui_response"); + assert.equal(response["value"], "SQLite"); + }).pipe(Effect.scoped, Effect.provide(layerTest)), + ); + it.effect("keeps the complete editor prefill editable and returns exact edited text", () => Effect.gen(function* () { const fake = yield* makeFakePi; diff --git a/packages/provider-pi/src/server/adapter.ts b/packages/provider-pi/src/server/adapter.ts index ac2c321323f1..2ace0eeaf9e4 100644 --- a/packages/provider-pi/src/server/adapter.ts +++ b/packages/provider-pi/src/server/adapter.ts @@ -3321,7 +3321,11 @@ function piQuestion( value: "", }, ]; - const question = recordString(event, "message") ?? recordString(event, "placeholder") ?? title; + // Extensions may send a blank placeholder, which is not a valid question. + const question = + [recordString(event, "message"), recordString(event, "placeholder")].find( + (text) => text !== undefined && text.trim().length > 0, + ) ?? title; return { id: questionId, header: title,