@machina.ai/cell-cli 1.56.0-rc1 → 1.59.0-rc1
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/package.json +3 -3
- package/dist/src/config/config.js +5 -3
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +5 -5
- package/dist/src/config/extension.test.js +1 -0
- package/dist/src/config/extension.test.js.map +1 -1
- package/dist/src/config/extensions/github.js +3 -3
- package/dist/src/config/extensions/github.js.map +1 -1
- package/dist/src/config/extensions/github.test.js +2 -0
- package/dist/src/config/extensions/github.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/nonInteractiveCliAgentSession.test.js +10 -2
- package/dist/src/nonInteractiveCliAgentSession.test.js.map +1 -1
- package/dist/src/ui/AppContainer.js +4 -1
- package/dist/src/ui/AppContainer.js.map +1 -1
- package/dist/src/ui/AppContainer.test.js +25 -2
- package/dist/src/ui/AppContainer.test.js.map +1 -1
- package/dist/src/ui/commands/modelCommand.js +1 -0
- package/dist/src/ui/commands/modelCommand.js.map +1 -1
- package/dist/src/ui/components/AsciiArt.d.ts +6 -6
- package/dist/src/ui/components/AsciiArt.js +6 -6
- package/dist/src/ui/components/ModelDialog.js +16 -3
- package/dist/src/ui/components/ModelDialog.js.map +1 -1
- package/dist/src/ui/components/ModelDialog.test.js +48 -78
- package/dist/src/ui/components/ModelDialog.test.js.map +1 -1
- package/dist/src/ui/hooks/useCommandCompletion.js +1 -9
- package/dist/src/ui/hooks/useCommandCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useCommandCompletion.test.js +2 -2
- package/dist/src/ui/hooks/useCommandCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +30 -11
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.test.js +117 -30
- package/dist/src/ui/hooks/useGeminiStream.test.js.map +1 -1
- package/dist/src/ui/hooks/useQuotaAndFallback.d.ts +1 -1
- package/dist/src/ui/hooks/useQuotaAndFallback.js +5 -2
- package/dist/src/ui/hooks/useQuotaAndFallback.js.map +1 -1
- package/dist/src/ui/hooks/useQuotaAndFallback.test.js +41 -3
- package/dist/src/ui/hooks/useQuotaAndFallback.test.js.map +1 -1
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.js +11 -3
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.js.map +1 -1
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.test.js +12 -0
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.test.js.map +1 -1
- package/dist/src/utils/handleAutoUpdate.test.js +2 -2
- package/dist/src/utils/sandbox-macos-permissive-open.sb +50 -0
- package/dist/src/utils/sandbox-macos-permissive-proxied.sb +50 -0
- package/dist/src/utils/sandbox-macos-profiles.test.js +53 -0
- package/dist/src/utils/sandbox-macos-profiles.test.js.map +1 -1
- package/dist/src/utils/sandbox-macos-restrictive-open.sb +49 -0
- package/dist/src/utils/sandbox-macos-restrictive-proxied.sb +50 -0
- package/dist/src/utils/sandbox-macos-strict-open.sb +50 -0
- package/dist/src/utils/sandbox-macos-strict-proxied.sb +50 -0
- package/dist/src/utils/sandboxBuiltinProfiles.js +252 -6
- package/dist/src/utils/sandboxBuiltinProfiles.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -31,6 +31,11 @@ const MockedGeminiClientClass = vi.hoisted(() => vi.fn().mockImplementation(func
|
|
|
31
31
|
this.startChat = mockStartChat;
|
|
32
32
|
this.sendMessageStream = mockSendMessageStream;
|
|
33
33
|
this.addHistory = vi.fn();
|
|
34
|
+
let mockHistory = [];
|
|
35
|
+
this.getHistory = vi.fn().mockImplementation(() => mockHistory);
|
|
36
|
+
this.setHistory = vi.fn().mockImplementation((newHistory) => {
|
|
37
|
+
mockHistory = [...newHistory];
|
|
38
|
+
});
|
|
34
39
|
this.generateContent = vi.fn().mockResolvedValue({
|
|
35
40
|
candidates: [
|
|
36
41
|
{ content: { parts: [{ text: 'Got it. Focusing on tests only.' }] } },
|
|
@@ -554,6 +559,12 @@ describe('useGeminiStream', () => {
|
|
|
554
559
|
0,
|
|
555
560
|
];
|
|
556
561
|
});
|
|
562
|
+
mockSendMessageStream.mockReturnValue((async function* () {
|
|
563
|
+
yield {
|
|
564
|
+
type: ServerGeminiEventType.Content,
|
|
565
|
+
value: 'Visible response text',
|
|
566
|
+
};
|
|
567
|
+
})());
|
|
557
568
|
await renderHookWithProviders(() => useGeminiStream(new MockedGeminiClientClass(mockConfig), [], mockAddItem, mockConfig, mockLoadedSettings, mockOnDebugMessage, mockHandleSlashCommand, false, () => 'vscode', () => { }, () => Promise.resolve(), false, () => { }, () => { }, () => { }, 80, 24));
|
|
558
569
|
// Trigger the onComplete callback with completed tools
|
|
559
570
|
await act(async () => {
|
|
@@ -646,7 +657,73 @@ describe('useGeminiStream', () => {
|
|
|
646
657
|
input: sentParts,
|
|
647
658
|
});
|
|
648
659
|
});
|
|
649
|
-
it('should
|
|
660
|
+
it('should auto-nudge the model when tool execution succeeds but model stream is empty', async () => {
|
|
661
|
+
const toolCallResponseParts = [{ text: 'tool final response' }];
|
|
662
|
+
const completedToolCalls = [
|
|
663
|
+
{
|
|
664
|
+
request: {
|
|
665
|
+
callId: 'call1',
|
|
666
|
+
name: 'tool1',
|
|
667
|
+
args: {},
|
|
668
|
+
isClientInitiated: false,
|
|
669
|
+
prompt_id: 'prompt-id-ack',
|
|
670
|
+
},
|
|
671
|
+
status: 'success',
|
|
672
|
+
responseSubmittedToGemini: false,
|
|
673
|
+
response: {
|
|
674
|
+
callId: 'call1',
|
|
675
|
+
responseParts: toolCallResponseParts,
|
|
676
|
+
errorType: undefined,
|
|
677
|
+
},
|
|
678
|
+
tool: {
|
|
679
|
+
displayName: 'MockTool',
|
|
680
|
+
},
|
|
681
|
+
invocation: {
|
|
682
|
+
getDescription: () => `Mock description`,
|
|
683
|
+
},
|
|
684
|
+
},
|
|
685
|
+
];
|
|
686
|
+
let callCount = 0;
|
|
687
|
+
mockSendMessageStream.mockImplementation(() => {
|
|
688
|
+
callCount += 1;
|
|
689
|
+
if (callCount === 1) {
|
|
690
|
+
return (async function* () { })();
|
|
691
|
+
}
|
|
692
|
+
else {
|
|
693
|
+
return (async function* () {
|
|
694
|
+
yield {
|
|
695
|
+
type: ServerGeminiEventType.Content,
|
|
696
|
+
value: 'I have analyzed the empty response. Here is the final answer.',
|
|
697
|
+
};
|
|
698
|
+
})();
|
|
699
|
+
}
|
|
700
|
+
});
|
|
701
|
+
let capturedOnComplete = null;
|
|
702
|
+
mockUseToolScheduler.mockImplementation((onComplete) => {
|
|
703
|
+
capturedOnComplete = onComplete;
|
|
704
|
+
return [
|
|
705
|
+
[],
|
|
706
|
+
mockScheduleToolCalls,
|
|
707
|
+
mockMarkToolsAsSubmitted,
|
|
708
|
+
vi.fn(),
|
|
709
|
+
mockCancelAllToolCalls,
|
|
710
|
+
0,
|
|
711
|
+
];
|
|
712
|
+
});
|
|
713
|
+
await renderHookWithProviders(() => useGeminiStream(new MockedGeminiClientClass(mockConfig), [], mockAddItem, mockConfig, mockLoadedSettings, mockOnDebugMessage, mockHandleSlashCommand, false, () => 'vscode', () => { }, () => Promise.resolve(), false, () => { }, () => { }, () => { }, 80, 24, undefined, () => 'focus on tests only'));
|
|
714
|
+
await act(async () => {
|
|
715
|
+
if (capturedOnComplete) {
|
|
716
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
717
|
+
await capturedOnComplete(completedToolCalls);
|
|
718
|
+
}
|
|
719
|
+
});
|
|
720
|
+
await waitFor(() => {
|
|
721
|
+
expect(mockSendMessageStream).toHaveBeenCalledTimes(2);
|
|
722
|
+
});
|
|
723
|
+
const sentParts = mockSendMessageStream.mock.calls[1][0];
|
|
724
|
+
expect(sentParts[0].text).toContain('[System: You successfully executed a tool but returned an empty response. Please analyze the tool output and explain your progress or final answer.]');
|
|
725
|
+
});
|
|
726
|
+
it('should handle all tool calls being cancelled by rolling back the history', async () => {
|
|
650
727
|
const cancelledToolCalls = [
|
|
651
728
|
{
|
|
652
729
|
request: {
|
|
@@ -696,6 +773,7 @@ describe('useGeminiStream', () => {
|
|
|
696
773
|
},
|
|
697
774
|
];
|
|
698
775
|
const client = new MockedGeminiClientClass(mockConfig);
|
|
776
|
+
client.setHistory([{ role: 'user', parts: [{ text: 'User prompt' }] }]);
|
|
699
777
|
// Capture the onComplete callback
|
|
700
778
|
let capturedOnComplete = null;
|
|
701
779
|
mockUseToolScheduler.mockImplementation((onComplete) => {
|
|
@@ -709,7 +787,20 @@ describe('useGeminiStream', () => {
|
|
|
709
787
|
0,
|
|
710
788
|
];
|
|
711
789
|
});
|
|
712
|
-
await renderHookWithProviders(() => useGeminiStream(client, [], mockAddItem, mockConfig, mockLoadedSettings, mockOnDebugMessage, mockHandleSlashCommand, false, () => 'vscode', () => { }, () => Promise.resolve(), false, () => { }, () => { }, () => { }, 80, 24));
|
|
790
|
+
const { result } = await renderHookWithProviders(() => useGeminiStream(client, [], mockAddItem, mockConfig, mockLoadedSettings, mockOnDebugMessage, mockHandleSlashCommand, false, () => 'vscode', () => { }, () => Promise.resolve(), false, () => { }, () => { }, () => { }, 80, 24));
|
|
791
|
+
// Call submitQuery to populate the user turn and set historyLengthAfterUserPromptRef
|
|
792
|
+
await act(async () => {
|
|
793
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
794
|
+
result.current.submitQuery('User prompt');
|
|
795
|
+
});
|
|
796
|
+
// Model issues a functionCall request, which appends to history
|
|
797
|
+
client.setHistory([
|
|
798
|
+
{ role: 'user', parts: [{ text: 'User prompt' }] },
|
|
799
|
+
{
|
|
800
|
+
role: 'model',
|
|
801
|
+
parts: [{ functionCall: { name: 'testTool', args: {} } }],
|
|
802
|
+
},
|
|
803
|
+
]);
|
|
713
804
|
// Trigger the onComplete callback with cancelled tools
|
|
714
805
|
await act(async () => {
|
|
715
806
|
if (capturedOnComplete) {
|
|
@@ -720,21 +811,12 @@ describe('useGeminiStream', () => {
|
|
|
720
811
|
});
|
|
721
812
|
await waitFor(() => {
|
|
722
813
|
expect(mockMarkToolsAsSubmitted).toHaveBeenCalledWith(['topic1', '1']);
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
id: 'topic1',
|
|
730
|
-
response: {},
|
|
731
|
-
},
|
|
732
|
-
},
|
|
733
|
-
{ text: CoreToolCallStatus.Cancelled },
|
|
734
|
-
],
|
|
735
|
-
});
|
|
736
|
-
// Ensure we do NOT call back to the API
|
|
737
|
-
expect(mockSendMessageStream).not.toHaveBeenCalled();
|
|
814
|
+
// Should NOT have appended cancellations via addHistory
|
|
815
|
+
expect(client.addHistory).not.toHaveBeenCalled();
|
|
816
|
+
// Should have rolled history back to pre-model length (1)
|
|
817
|
+
expect(client.getHistory().length).toBe(1);
|
|
818
|
+
// Ensure we do NOT call back to the API a second time (only the initial user turn was sent)
|
|
819
|
+
expect(mockSendMessageStream).toHaveBeenCalledTimes(1);
|
|
738
820
|
});
|
|
739
821
|
});
|
|
740
822
|
it('should record tool responses in history when the model was switched due to a quota error', async () => {
|
|
@@ -972,7 +1054,7 @@ describe('useGeminiStream', () => {
|
|
|
972
1054
|
expect(failureHintIndex).toBe(-1);
|
|
973
1055
|
expect(noteIndex).toBeLessThan(stopIndex);
|
|
974
1056
|
});
|
|
975
|
-
it('should
|
|
1057
|
+
it('should rollback multiple cancelled tool calls rather than appending them to history', async () => {
|
|
976
1058
|
const cancelledToolCall1 = {
|
|
977
1059
|
request: {
|
|
978
1060
|
callId: 'cancel-1',
|
|
@@ -1033,6 +1115,7 @@ describe('useGeminiStream', () => {
|
|
|
1033
1115
|
};
|
|
1034
1116
|
const allCancelledTools = [cancelledToolCall1, cancelledToolCall2];
|
|
1035
1117
|
const client = new MockedGeminiClientClass(mockConfig);
|
|
1118
|
+
client.setHistory([{ role: 'user', parts: [{ text: 'User prompt' }] }]);
|
|
1036
1119
|
let capturedOnComplete = null;
|
|
1037
1120
|
mockUseToolScheduler.mockImplementation((onComplete) => {
|
|
1038
1121
|
capturedOnComplete = onComplete;
|
|
@@ -1045,7 +1128,17 @@ describe('useGeminiStream', () => {
|
|
|
1045
1128
|
0,
|
|
1046
1129
|
];
|
|
1047
1130
|
});
|
|
1048
|
-
await renderHookWithProviders(() => useGeminiStream(client, [], mockAddItem, mockConfig, mockLoadedSettings, mockOnDebugMessage, mockHandleSlashCommand, false, () => 'vscode', () => { }, () => Promise.resolve(), false, () => { }, () => { }, () => { }, 80, 24));
|
|
1131
|
+
const { result } = await renderHookWithProviders(() => useGeminiStream(client, [], mockAddItem, mockConfig, mockLoadedSettings, mockOnDebugMessage, mockHandleSlashCommand, false, () => 'vscode', () => { }, () => Promise.resolve(), false, () => { }, () => { }, () => { }, 80, 24));
|
|
1132
|
+
// Call submitQuery to populate the user turn and set historyLengthAfterUserPromptRef
|
|
1133
|
+
await act(async () => {
|
|
1134
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1135
|
+
result.current.submitQuery('User prompt');
|
|
1136
|
+
});
|
|
1137
|
+
// Model issues model turns, which appends to history
|
|
1138
|
+
client.setHistory([
|
|
1139
|
+
{ role: 'user', parts: [{ text: 'User prompt' }] },
|
|
1140
|
+
{ role: 'model', parts: [{ functionCall: { name: 'toolA', args: {} } }] },
|
|
1141
|
+
]);
|
|
1049
1142
|
// Trigger the onComplete callback with multiple cancelled tools
|
|
1050
1143
|
await act(async () => {
|
|
1051
1144
|
if (capturedOnComplete) {
|
|
@@ -1060,18 +1153,12 @@ describe('useGeminiStream', () => {
|
|
|
1060
1153
|
'cancel-1',
|
|
1061
1154
|
'cancel-2',
|
|
1062
1155
|
]);
|
|
1063
|
-
// Crucially, addHistory should be called
|
|
1064
|
-
expect(client.addHistory).
|
|
1065
|
-
//
|
|
1066
|
-
expect(client.
|
|
1067
|
-
role: 'user',
|
|
1068
|
-
parts: [
|
|
1069
|
-
...cancelledToolCall1.response.responseParts,
|
|
1070
|
-
...cancelledToolCall2.response.responseParts,
|
|
1071
|
-
],
|
|
1072
|
-
});
|
|
1156
|
+
// Crucially, addHistory should NOT be called
|
|
1157
|
+
expect(client.addHistory).not.toHaveBeenCalled();
|
|
1158
|
+
// Instead, history should be rolled back to pre-model length (1)
|
|
1159
|
+
expect(client.getHistory().length).toBe(1);
|
|
1073
1160
|
// No message should be sent back to the API for a turn with only cancellations
|
|
1074
|
-
expect(mockSendMessageStream).
|
|
1161
|
+
expect(mockSendMessageStream).toHaveBeenCalledTimes(1);
|
|
1075
1162
|
});
|
|
1076
1163
|
});
|
|
1077
1164
|
it('should not flicker streaming state to Idle between tool completion and submission', async () => {
|