@volter/supercode-frontend-vscode 0.1.43 → 0.1.45

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.
Files changed (2) hide show
  1. package/dist/extension.js +57 -48
  2. package/package.json +1 -1
package/dist/extension.js CHANGED
@@ -411,7 +411,7 @@ export async function activate(context) {
411
411
  const boundId = (resource) => resolveSessionBinding(resource, controls?.state.sessions ?? [], resourceBindings);
412
412
  let applying = Promise.resolve();
413
413
  // the reason the last send from a new chat made no conversation, said by that draft's request handler
414
- let refusedSend;
414
+ const refusedSends = new Map(); // by the draft's resource ('' when the send named none)
415
415
  let pendingDraft;
416
416
  let focusedResource;
417
417
  let focusGeneration = 0;
@@ -734,12 +734,10 @@ export async function activate(context) {
734
734
  if (!controls)
735
735
  throw new Error('This host does not expose harness or model configuration.');
736
736
  const active = managed();
737
- // A send from a blank chat lands here, and the workbench does not show its error: say it, then refuse.
737
+ // its caller (a new chat's first send) says the refusal in that chat
738
738
  const refusal = busyRefusal(active, 'starting a new chat');
739
- if (refusal) {
740
- void vscode.window.showWarningMessage(refusal);
739
+ if (refusal)
741
740
  throw new Error(refusal);
742
- }
743
741
  if (active)
744
742
  await saveManagedHistory(active);
745
743
  const state = await controls.select(selection);
@@ -750,8 +748,6 @@ export async function activate(context) {
750
748
  const openNewChat = async () => {
751
749
  if (!controls || !granted.has('chatSessionsProvider'))
752
750
  throw new Error('This host does not expose native conversation creation.');
753
- // Its callers (the new-chat pickers) swallow the cancellation, so the warning is the one message shown. An error
754
- // would reach the person as a bare "Canceled" or not at all through the contributed-command boundary.
755
751
  // A turn running elsewhere does not stop a draft: its first send is refused there, in the chat (`create`).
756
752
  // Code-OSS materializes this untitled session on first send, awaiting our
757
753
  // newChatSessionItemHandler before accepting/clearing the draft. Never boot
@@ -818,7 +814,6 @@ export async function activate(context) {
818
814
  try {
819
815
  // Open before the picker: a send can beat its result across the extension-
820
816
  // host boundary. Materialization awaits this exact draft's choice too.
821
- // Inside the try: a busy refusal is a cancellation already explained.
822
817
  const opened = draft = await openNewChat();
823
818
  picking = (async () => {
824
819
  const choice = await pick();
@@ -847,6 +842,44 @@ export async function activate(context) {
847
842
  // Publish capability-honest input groups only after the handoff descriptor is available.
848
843
  if (controls?.state.connection)
849
844
  await connectManaged().catch(error => log.warn(`Could not attach before registering chat input: ${String(error)}`));
845
+ const createConversation = async (inputState) => {
846
+ if (!controls)
847
+ throw new Error('The host does not expose conversation creation.');
848
+ const busy = busyRefusal(managed(), 'starting a new chat');
849
+ if (busy)
850
+ throw new Error(busy);
851
+ const draft = activeDraft();
852
+ // the picker ends in a cancellation for a sign-in choice too: the draft's choice says which (sign-in is refused
853
+ // below, in the chat); a draft that went away is the real cancellation
854
+ await draft?.choosing?.catch(() => undefined);
855
+ if (draft && activeDraft() !== draft)
856
+ throw new vscode.CancellationError();
857
+ await controls.refresh();
858
+ controlsChanged.fire();
859
+ const choice = draft?.choice;
860
+ const loginHarness = choice?.kind === 'signIn' ? choice.harness : undefined;
861
+ if (loginHarness && !controls.state.harnesses.some(h => h.id === loginHarness && h.autoStart)) {
862
+ throw new Error(`Finish signing in with ${harnessDisplayName(loginHarness)} before sending.`);
863
+ }
864
+ if (choice?.kind !== 'agent' && controls.state.setup && !controls.state.setup.ready) {
865
+ throw new Error('Sign in before sending; use Check again after signing in.');
866
+ }
867
+ const selection = choice?.kind === 'agent' ? choice.selection
868
+ : { harness: loginHarness ?? controls.state.selection.harness, model: '', effort: '' };
869
+ const pending = applying.then(() => applySelection(selection));
870
+ applying = pending.then(() => undefined, () => undefined);
871
+ const connection = await pending;
872
+ // The picker shows the host's default until someone changes it; only a change is the person's choice.
873
+ const selected = inputState.groups.find(group => group.id === 'permissions')?.selected?.id;
874
+ const picked = selected === 'ask' || selected === 'autoApprove' ? selected : permission ?? newChatDefault();
875
+ choosePermission(connection.id, picked, permission !== undefined ? null : newChatDefault());
876
+ permission = undefined;
877
+ if (pendingDraft === draft) {
878
+ pendingDraft = undefined;
879
+ controlsChanged.fire();
880
+ }
881
+ return connection;
882
+ };
850
883
  const providerControls = {
851
884
  changed: controlsChanged.event,
852
885
  currentOptions,
@@ -885,45 +918,19 @@ export async function activate(context) {
885
918
  else
886
919
  permission = turnPermission(value);
887
920
  },
921
+ // A send that makes no conversation (another turn runs, or the host or a sign-in refuses it) answers no item: the
922
+ // host then runs the request on the draft itself, and its handler says why in the chat. A rejection here reaches
923
+ // nobody (the host's acceptInput drops it), so every refusal goes that way (#1282 review).
888
924
  create: async (inputState) => {
889
- if (!controls)
890
- throw new Error('The host does not expose conversation creation.');
891
- // A send while another turn runs makes no conversation: the host then runs the request on the draft itself, and
892
- // its handler says why in the chat. A rejection here reaches nobody (the host's acceptInput drops it).
893
- const busy = busyRefusal(managed(), 'starting a new chat');
894
- if (busy) {
895
- refusedSend = busy;
896
- return undefined;
897
- }
898
- const draft = activeDraft();
899
- await draft?.choosing;
900
- if (draft && activeDraft() !== draft)
901
- throw new vscode.CancellationError();
902
- await controls.refresh();
903
- controlsChanged.fire();
904
- const choice = draft?.choice;
905
- const loginHarness = choice?.kind === 'signIn' ? choice.harness : undefined;
906
- if (loginHarness && !controls.state.harnesses.some(h => h.id === loginHarness && h.autoStart)) {
907
- throw new Error(`Finish signing in with ${harnessDisplayName(loginHarness)} before sending. Your draft is kept.`);
908
- }
909
- if (choice?.kind !== 'agent' && controls.state.setup && !controls.state.setup.ready) {
910
- throw new Error('Sign in before sending. Your draft is kept; use Check again after signing in.');
925
+ try {
926
+ return await createConversation(inputState);
911
927
  }
912
- const selection = choice?.kind === 'agent' ? choice.selection
913
- : { harness: loginHarness ?? controls.state.selection.harness, model: '', effort: '' };
914
- const pending = applying.then(() => applySelection(selection));
915
- applying = pending.then(() => undefined, () => undefined);
916
- const connection = await pending;
917
- // The picker shows the host's default until someone changes it; only a change is the person's choice.
918
- const selected = inputState.groups.find(group => group.id === 'permissions')?.selected?.id;
919
- const picked = selected === 'ask' || selected === 'autoApprove' ? selected : permission ?? newChatDefault();
920
- choosePermission(connection.id, picked, permission !== undefined ? null : newChatDefault());
921
- permission = undefined;
922
- if (pendingDraft === draft) {
923
- pendingDraft = undefined;
924
- controlsChanged.fire();
928
+ catch (error) {
929
+ if (error instanceof vscode.CancellationError)
930
+ throw error;
931
+ refusedSends.set(activeDraft()?.resource.toString() ?? '', String(error?.message ?? error));
932
+ return undefined;
925
933
  }
926
- return connection;
927
934
  },
928
935
  resolve: (resource) => connectionFor(resource, false),
929
936
  attached: (connection) => attachedIds.has(connection.id),
@@ -1170,11 +1177,13 @@ export async function activate(context) {
1170
1177
  const handler = async (request, chatContext, stream, token) => {
1171
1178
  await applying;
1172
1179
  const requestedResource = chatContext.chatSessionContext?.chatSessionItem?.resource;
1173
- if (refusedSend && requestedResource?.path.startsWith('/untitled-') && !boundId(requestedResource)) {
1174
- const refusal = refusedSend;
1175
- refusedSend = undefined;
1180
+ const refusedKey = requestedResource?.path.startsWith('/untitled-') && !boundId(requestedResource)
1181
+ ? [requestedResource.toString(), ''].find(key => refusedSends.has(key)) : undefined;
1182
+ if (refusedKey !== undefined) {
1183
+ const refusal = refusedSends.get(refusedKey);
1184
+ refusedSends.delete(refusedKey);
1176
1185
  // thrown as is: the workbench writes a handler's error into the chat
1177
- throw new Error(`${refusal} Nothing was sent; send it again in a new chat once that turn has ended.`);
1186
+ throw new Error(`${refusal} Nothing was sent; send it again in a new chat.`);
1178
1187
  }
1179
1188
  if (controls?.state.setup && !controls.state.setup.ready) {
1180
1189
  stream.markdown('Sign in before sending a message. Use **New Chat: Choose Agent** to get started.');
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@volter/supercode-frontend-vscode",
3
3
  "displayName": "Volter Harness",
4
- "version": "0.1.43",
4
+ "version": "0.1.45",
5
5
  "type": "module",
6
6
  "description": "VS Code chat-view frontend for an existing Volter Harness SDK runtime",
7
7
  "publisher": "volter-ai-dev",