@alumbwe/anvil 1.0.42 → 1.0.50
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/bin/anvil.js +18 -0
- package/package.json +13 -6
- package/src/agents/bundled-agents.generated.ts +1 -1
- package/src/index.tsx +27 -4
- package/src/login/plain-login.ts +60 -0
- package/src/login/supabase-auth.ts +346 -0
- package/src/utils/anvil-client.ts +4 -0
- package/src/utils/auth.ts +16 -4
- package/src/utils/config-dir.ts +1 -1
- package/vendor/@anvil/common/src/constants/deepseek-direct.ts +30 -1
- package/vendor/@anvil/common/src/util/project-ignore.ts +4 -3
- package/vendor/@anvil/sdk/dist/index.cjs +46 -10
- package/vendor/@anvil/sdk/dist/index.mjs +46 -10
- package/src/commands/__tests__/anvil-command-aliases.test.ts +0 -56
- package/src/commands/__tests__/bash-command.test.ts +0 -445
- package/src/commands/__tests__/command-args.test.ts +0 -349
- package/src/commands/__tests__/copy-conversation-clipboard.test.ts +0 -108
- package/src/commands/__tests__/copy-conversation.test.ts +0 -226
- package/src/commands/__tests__/diagnostics-command.test.ts +0 -35
- package/src/commands/__tests__/image.test.ts +0 -99
- package/src/commands/__tests__/init.test.ts +0 -456
- package/src/commands/__tests__/new-command-rotates-chat.test.ts +0 -91
- package/src/commands/__tests__/process-diagnostics.test.ts +0 -54
- package/src/commands/__tests__/prompt-builders.test.ts +0 -28
- package/src/commands/__tests__/router-input.test.ts +0 -298
- package/src/components/__tests__/ad-banner.test.tsx +0 -83
- package/src/components/__tests__/anvil-landing-heading-row.test.tsx +0 -91
- package/src/components/__tests__/anvil-model-selector.test.tsx +0 -519
- package/src/components/__tests__/anvil-offer-invariants.test.ts +0 -54
- package/src/components/__tests__/anvil-takeover-prompt.test.tsx +0 -212
- package/src/components/__tests__/chat-input-bar.test.tsx +0 -130
- package/src/components/__tests__/grid-layout.integration.test.tsx +0 -304
- package/src/components/__tests__/grid-layout.test.tsx +0 -1051
- package/src/components/__tests__/message-block.completion.test.tsx +0 -104
- package/src/components/__tests__/message-block.streaming.test.tsx +0 -78
- package/src/components/__tests__/message-with-agents.test.tsx +0 -579
- package/src/components/__tests__/multiline-input.test.tsx +0 -1132
- package/src/components/__tests__/queue-panel.test.tsx +0 -398
- package/src/components/__tests__/selectable-list.test.ts +0 -232
- package/src/components/__tests__/status-bar.test.tsx +0 -44
- package/src/components/__tests__/status-indicator.test.tsx +0 -204
- package/src/components/__tests__/terminal-thinking-orb.test.tsx +0 -111
- package/src/components/__tests__/user-error-banner.test.tsx +0 -102
- package/src/components/ask-user/__tests__/multiple-choice-form.test.ts +0 -432
- package/src/components/ask-user/__tests__/validation.test.ts +0 -213
- package/src/components/tools/__tests__/apply-patch.test.tsx +0 -84
- package/src/components/tools/__tests__/code-search.test.tsx +0 -45
- package/src/components/tools/__tests__/gravity-index.test.ts +0 -76
- package/src/components/tools/__tests__/render-ui.test.tsx +0 -92
- package/src/components/tools/__tests__/run-terminal-command.test.ts +0 -233
- package/src/contexts/__tests__/chat-runtime-context.test.tsx +0 -149
- package/src/data/slash-commands.test.ts +0 -24
- package/src/hooks/__tests__/holds-live-anvil-slot.test.ts +0 -49
- package/src/hooks/__tests__/session-fetch-signal.test.ts +0 -63
- package/src/hooks/__tests__/use-activity-query.test.ts +0 -1000
- package/src/hooks/__tests__/use-ask-user-bridge.test.ts +0 -176
- package/src/hooks/__tests__/use-auth-query.test.ts +0 -21
- package/src/hooks/__tests__/use-chat-input-remount.test.tsx +0 -66
- package/src/hooks/__tests__/use-clipboard.test.tsx +0 -73
- package/src/hooks/__tests__/use-connection-status.test.ts +0 -112
- package/src/hooks/__tests__/use-directory-browser.test.ts +0 -203
- package/src/hooks/__tests__/use-gravity-ad.test.ts +0 -73
- package/src/hooks/__tests__/use-grid-layout.test.ts +0 -349
- package/src/hooks/__tests__/use-input-history.test.ts +0 -699
- package/src/hooks/__tests__/use-message-queue-editing.test.tsx +0 -209
- package/src/hooks/__tests__/use-message-queue.test.tsx +0 -71
- package/src/hooks/__tests__/use-path-tab-completion.test.ts +0 -315
- package/src/hooks/__tests__/use-queue-controls.test.ts +0 -68
- package/src/hooks/__tests__/use-queue-ui.test.tsx +0 -83
- package/src/hooks/__tests__/use-searchable-list.test.ts +0 -359
- package/src/hooks/__tests__/use-send-message-timer.test.ts +0 -146
- package/src/hooks/__tests__/use-suggestion-engine-mention.test.ts +0 -361
- package/src/hooks/__tests__/use-suggestion-engine.test.ts +0 -485
- package/src/hooks/__tests__/use-terminal-focus.test.ts +0 -66
- package/src/hooks/__tests__/use-terminal-layout.test.ts +0 -675
- package/src/hooks/__tests__/use-timeout.test.ts +0 -330
- package/src/hooks/__tests__/use-usage-query.test.ts +0 -502
- package/src/hooks/__tests__/use-user-details-query.test.ts +0 -195
- package/src/hooks/helpers/__tests__/send-message.test.ts +0 -1918
- package/src/init/__tests__/init-direnv.test.ts +0 -526
- package/src/state/__tests__/chat-store-focus.test.ts +0 -22
- package/src/state/__tests__/feedback-store.test.ts +0 -257
- package/src/utils/__tests__/active-run.test.ts +0 -140
- package/src/utils/__tests__/activity-tracker.test.ts +0 -440
- package/src/utils/__tests__/agent-display.test.ts +0 -139
- package/src/utils/__tests__/analytics-client.test.ts +0 -262
- package/src/utils/__tests__/anonymous-id.test.ts +0 -74
- package/src/utils/__tests__/anvil-api.test.ts +0 -578
- package/src/utils/__tests__/anvil-instance-owner.test.ts +0 -69
- package/src/utils/__tests__/anvil-model-navigation.test.ts +0 -102
- package/src/utils/__tests__/anvil-premium-reset.test.ts +0 -79
- package/src/utils/__tests__/anvil-referral-cache.test.ts +0 -116
- package/src/utils/__tests__/anvil-session-api.test.ts +0 -215
- package/src/utils/__tests__/anvil-session-display.test.ts +0 -23
- package/src/utils/__tests__/anvil-streak-line.test.ts +0 -217
- package/src/utils/__tests__/arrays.test.ts +0 -264
- package/src/utils/__tests__/bash-context-processor.test.ts +0 -38
- package/src/utils/__tests__/block-processor.test.ts +0 -810
- package/src/utils/__tests__/chat-history.test.ts +0 -203
- package/src/utils/__tests__/chat-input-key-intercept.test.ts +0 -40
- package/src/utils/__tests__/chat-meta.test.ts +0 -130
- package/src/utils/__tests__/clipboard-linux.test.ts +0 -359
- package/src/utils/__tests__/clipboard.test.ts +0 -910
- package/src/utils/__tests__/code-search-summary.test.ts +0 -84
- package/src/utils/__tests__/collapse-helpers.test.ts +0 -1109
- package/src/utils/__tests__/error-handling.test.ts +0 -658
- package/src/utils/__tests__/exit-cleanly.test.ts +0 -110
- package/src/utils/__tests__/feedback-helpers.test.ts +0 -444
- package/src/utils/__tests__/feedback-submission.test.ts +0 -26
- package/src/utils/__tests__/fetch-usage.test.ts +0 -355
- package/src/utils/__tests__/fingerprint.test.ts +0 -144
- package/src/utils/__tests__/fixtures/terminal-command-broker-child.ts +0 -7
- package/src/utils/__tests__/fixtures/terminal-command-broker-entry.ts +0 -3
- package/src/utils/__tests__/fixtures/terminal-command-broker-owner.ts +0 -33
- package/src/utils/__tests__/format-elapsed-time.test.ts +0 -103
- package/src/utils/__tests__/format-timeout.test.ts +0 -87
- package/src/utils/__tests__/image-dimensions.test.ts +0 -249
- package/src/utils/__tests__/image-processor.test.ts +0 -209
- package/src/utils/__tests__/implementor-helpers.test.ts +0 -1458
- package/src/utils/__tests__/keyboard-actions.test.ts +0 -660
- package/src/utils/__tests__/layout-helpers.test.ts +0 -36
- package/src/utils/__tests__/lazy-response-ads.test.ts +0 -167
- package/src/utils/__tests__/log-shipper.test.ts +0 -53
- package/src/utils/__tests__/markdown-renderer.test.tsx +0 -421
- package/src/utils/__tests__/message-block-helpers.test.ts +0 -1263
- package/src/utils/__tests__/message-updater.test.ts +0 -645
- package/src/utils/__tests__/osc-timeout-scenarios.test.ts +0 -172
- package/src/utils/__tests__/pending-attachments.test.ts +0 -277
- package/src/utils/__tests__/polling-backoff.test.ts +0 -51
- package/src/utils/__tests__/queue-panel-actions.test.ts +0 -148
- package/src/utils/__tests__/run-state-storage.test.ts +0 -919
- package/src/utils/__tests__/safe-json.test.ts +0 -77
- package/src/utils/__tests__/sdk-event-handlers.test.ts +0 -685
- package/src/utils/__tests__/send-message-helpers.test.ts +0 -1898
- package/src/utils/__tests__/send-message-timer.test.ts +0 -64
- package/src/utils/__tests__/settings.test.ts +0 -99
- package/src/utils/__tests__/strings.test.ts +0 -192
- package/src/utils/__tests__/terminal-color-detection.test.ts +0 -425
- package/src/utils/__tests__/terminal-command-broker.test.ts +0 -528
- package/src/utils/__tests__/terminal-enter-detection.test.ts +0 -77
- package/src/utils/__tests__/terminal-io.test.ts +0 -137
- package/src/utils/__tests__/terminal-protocol-controller.test.ts +0 -119
- package/src/utils/__tests__/text-layout.test.ts +0 -82
- package/src/utils/__tests__/theme-platform-detection.test.ts +0 -125
- package/src/utils/__tests__/think-tag-parser.test.ts +0 -159
- package/src/utils/__tests__/trace-writer.test.ts +0 -223
- package/src/utils/__tests__/trim-chat-logs.test.ts +0 -78
- package/src/utils/__tests__/usage-banner-state.test.ts +0 -298
- package/src/utils/__tests__/validation-error-formatting.test.ts +0 -126
- package/src/utils/__tests__/windows-terminal-health.test.ts +0 -101
- package/src/utils/__tests__/write-file-atomic.test.ts +0 -127
- package/vendor/@anvil/common/src/__tests__/agent-validation.test.ts +0 -846
- package/vendor/@anvil/common/src/__tests__/anvil-model-availability.test.ts +0 -101
- package/vendor/@anvil/common/src/__tests__/anvil-models.test.ts +0 -1408
- package/vendor/@anvil/common/src/__tests__/anvil-public-data-use-copy.test.ts +0 -258
- package/vendor/@anvil/common/src/__tests__/anvil-referral-tiers.test.ts +0 -48
- package/vendor/@anvil/common/src/__tests__/anvil-spend-ceilings.test.ts +0 -282
- package/vendor/@anvil/common/src/__tests__/anvil-trust.test.ts +0 -526
- package/vendor/@anvil/common/src/__tests__/deepseek-direct.test.ts +0 -68
- package/vendor/@anvil/common/src/__tests__/disposable-email.test.ts +0 -132
- package/vendor/@anvil/common/src/__tests__/dynamic-agent-template-schema.test.ts +0 -422
- package/vendor/@anvil/common/src/__tests__/env-ci.test.ts +0 -167
- package/vendor/@anvil/common/src/__tests__/env-process.test.ts +0 -145
- package/vendor/@anvil/common/src/__tests__/foreign-client-shipped-agents.test.ts +0 -234
- package/vendor/@anvil/common/src/__tests__/foreign-client-signals.test.ts +0 -379
- package/vendor/@anvil/common/src/__tests__/free-agents.test.ts +0 -807
- package/vendor/@anvil/common/src/__tests__/gravity-capi.test.ts +0 -154
- package/vendor/@anvil/common/src/__tests__/handlesteps-parsing.test.ts +0 -246
- package/vendor/@anvil/common/src/__tests__/kimi-k3-god-only.test.ts +0 -77
- package/vendor/@anvil/common/src/__tests__/model-config.test.ts +0 -89
- package/vendor/@anvil/common/src/__tests__/project-file-tree.test.ts +0 -298
- package/vendor/@anvil/common/src/__tests__/provisioned-model-tiers.test.ts +0 -116
- package/vendor/@anvil/common/src/__tests__/reasoning-effort.test.ts +0 -167
- package/vendor/@anvil/common/src/__tests__/reddit-capi.test.ts +0 -132
- package/vendor/@anvil/common/src/__tests__/response-ad-positions.test.ts +0 -72
- package/vendor/@anvil/common/src/__tests__/user-state.test.ts +0 -30
- package/vendor/@anvil/common/src/constants/__tests__/anvil-onboarding-gate.test.ts +0 -63
- package/vendor/@anvil/common/src/constants/__tests__/anvil-onboarding.test.ts +0 -246
- package/vendor/@anvil/common/src/constants/__tests__/cf-worker-signals.test.ts +0 -106
- package/vendor/@anvil/common/src/testing/TESTING_PATTERNS.md +0 -351
- package/vendor/@anvil/common/src/testing/anvil-offer-invariants.ts +0 -169
- package/vendor/@anvil/common/src/testing/errors.ts +0 -33
- package/vendor/@anvil/common/src/testing/fixtures/agent-runtime.ts +0 -334
- package/vendor/@anvil/common/src/testing/impl/agent-runtime.ts +0 -6
- package/vendor/@anvil/common/src/testing/index.ts +0 -84
- package/vendor/@anvil/common/src/testing/mock-modules.ts +0 -53
- package/vendor/@anvil/common/src/testing/mock-types.ts +0 -123
- package/vendor/@anvil/common/src/testing/mocks/analytics.ts +0 -261
- package/vendor/@anvil/common/src/testing/mocks/child-process.ts +0 -93
- package/vendor/@anvil/common/src/testing/mocks/crypto.ts +0 -218
- package/vendor/@anvil/common/src/testing/mocks/database.ts +0 -337
- package/vendor/@anvil/common/src/testing/mocks/fetch.ts +0 -219
- package/vendor/@anvil/common/src/testing/mocks/filesystem.ts +0 -166
- package/vendor/@anvil/common/src/testing/mocks/index.ts +0 -101
- package/vendor/@anvil/common/src/testing/mocks/logger.ts +0 -135
- package/vendor/@anvil/common/src/testing/mocks/stream.ts +0 -313
- package/vendor/@anvil/common/src/testing/mocks/timers.ts +0 -132
- package/vendor/@anvil/common/src/testing/mocks/tree-sitter.ts +0 -127
- package/vendor/@anvil/common/src/testing/setup.ts +0 -282
- package/vendor/@anvil/common/src/tools/__tests__/compile-tool-definitions.test.ts +0 -34
- package/vendor/@anvil/common/src/tools/params/__tests__/coerce-to-array.test.ts +0 -213
- package/vendor/@anvil/common/src/tools/params/__tests__/read-docs.test.ts +0 -47
- package/vendor/@anvil/common/src/tools/params/__tests__/render-ui.test.ts +0 -65
- package/vendor/@anvil/common/src/tools/params/tool/__tests__/run-terminal-command-timeout.test.ts +0 -49
- package/vendor/@anvil/common/src/types/__tests__/dynamic-agent-template.test.ts +0 -20
- package/vendor/@anvil/common/src/util/__tests__/ad-user-agent.test.ts +0 -26
- package/vendor/@anvil/common/src/util/__tests__/analytics-dispatcher.test.ts +0 -122
- package/vendor/@anvil/common/src/util/__tests__/analytics-log.test.ts +0 -102
- package/vendor/@anvil/common/src/util/__tests__/analytics-sampling.test.ts +0 -143
- package/vendor/@anvil/common/src/util/__tests__/anvil-streak.test.ts +0 -202
- package/vendor/@anvil/common/src/util/__tests__/anvil-usage-summary.test.ts +0 -193
- package/vendor/@anvil/common/src/util/__tests__/axiom-only-log.test.ts +0 -140
- package/vendor/@anvil/common/src/util/__tests__/client-user-agent.test.ts +0 -148
- package/vendor/@anvil/common/src/util/__tests__/engagement-tracker.test.ts +0 -115
- package/vendor/@anvil/common/src/util/__tests__/env-file-path.test.ts +0 -57
- package/vendor/@anvil/common/src/util/__tests__/error-abort.test.ts +0 -774
- package/vendor/@anvil/common/src/util/__tests__/error-api-details.test.ts +0 -206
- package/vendor/@anvil/common/src/util/__tests__/file-read-limits.test.ts +0 -173
- package/vendor/@anvil/common/src/util/__tests__/format-code-search.test.ts +0 -60
- package/vendor/@anvil/common/src/util/__tests__/log-mirror.test.ts +0 -31
- package/vendor/@anvil/common/src/util/__tests__/messages.test.ts +0 -1252
- package/vendor/@anvil/common/src/util/__tests__/partial-json-delta.test.ts +0 -505
- package/vendor/@anvil/common/src/util/__tests__/path.test.ts +0 -22
- package/vendor/@anvil/common/src/util/__tests__/project-ignore.test.ts +0 -90
- package/vendor/@anvil/common/src/util/__tests__/promise.test.ts +0 -325
- package/vendor/@anvil/common/src/util/__tests__/rate-limit.test.ts +0 -28
- package/vendor/@anvil/common/src/util/__tests__/reddit-anvil-retention.test.ts +0 -130
- package/vendor/@anvil/common/src/util/__tests__/saxy.test.ts +0 -1008
- package/vendor/@anvil/common/src/util/__tests__/split-data.test.ts +0 -289
- package/vendor/@anvil/common/src/util/__tests__/string.test.ts +0 -239
- package/vendor/@anvil/common/src/util/__tests__/thread-title.test.ts +0 -70
- package/vendor/@anvil/common/src/util/__tests__/tool-result-media-order.test.ts +0 -108
- package/vendor/@anvil/common/src/util/__tests__/ttft-histogram.test.ts +0 -180
- package/vendor/@anvil/common/src/util/__tests__/with-timeout.test.ts +0 -24
- package/vendor/@anvil/common/src/util/__tests__/zoned-time.test.ts +0 -88
- package/vendor/@anvil/common/src/util/skills.test.ts +0 -44
- package/vendor/@anvil/sdk/dist/index.cjs.map +0 -440
- package/vendor/@anvil/sdk/dist/index.mjs.map +0 -440
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import { renderToStaticMarkup } from 'react-dom/server'
|
|
4
|
-
|
|
5
|
-
import { initializeThemeStore } from '../../../hooks/use-theme'
|
|
6
|
-
import { chatThemes } from '../../../utils/theme-system'
|
|
7
|
-
import { getToolComponent, renderToolComponent } from '../registry'
|
|
8
|
-
|
|
9
|
-
import type { ToolBlock } from '../types'
|
|
10
|
-
|
|
11
|
-
initializeThemeStore()
|
|
12
|
-
|
|
13
|
-
const createToolBlock = (
|
|
14
|
-
operation: Record<string, unknown>,
|
|
15
|
-
): ToolBlock & { toolName: 'apply_patch' } => ({
|
|
16
|
-
type: 'tool',
|
|
17
|
-
toolName: 'apply_patch',
|
|
18
|
-
toolCallId: 'apply-patch-test-id',
|
|
19
|
-
input: { operation },
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
const renderOptions = {
|
|
23
|
-
availableWidth: 80,
|
|
24
|
-
indentationOffset: 0,
|
|
25
|
-
labelWidth: 0,
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
describe('ApplyPatchComponent', () => {
|
|
29
|
-
test('is registered for apply_patch tool calls', () => {
|
|
30
|
-
expect(getToolComponent('apply_patch')).toBeDefined()
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
test('renders create_file operation', () => {
|
|
34
|
-
const toolBlock = createToolBlock({
|
|
35
|
-
type: 'create_file',
|
|
36
|
-
path: 'src/new-file.ts',
|
|
37
|
-
diff: '@@\n+export const value = 1\n',
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
const result = renderToolComponent(toolBlock, chatThemes.dark, renderOptions)
|
|
41
|
-
|
|
42
|
-
expect(result).toBeDefined()
|
|
43
|
-
expect(result?.content).toBeDefined()
|
|
44
|
-
|
|
45
|
-
const markup = renderToStaticMarkup(result?.content as React.ReactElement)
|
|
46
|
-
expect(markup).toContain('Create')
|
|
47
|
-
expect(markup).toContain('src/new-file.ts')
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
test('renders update_file operation with diff content', () => {
|
|
51
|
-
const toolBlock = createToolBlock({
|
|
52
|
-
type: 'update_file',
|
|
53
|
-
path: 'src/existing.ts',
|
|
54
|
-
diff: '@@\n-oldLine\n+newLine\n',
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
const result = renderToolComponent(toolBlock, chatThemes.dark, renderOptions)
|
|
58
|
-
|
|
59
|
-
expect(result).toBeDefined()
|
|
60
|
-
expect(result?.content).toBeDefined()
|
|
61
|
-
|
|
62
|
-
const markup = renderToStaticMarkup(result?.content as React.ReactElement)
|
|
63
|
-
expect(markup).toContain('Edit')
|
|
64
|
-
expect(markup).toContain('src/existing.ts')
|
|
65
|
-
expect(markup).toContain('-oldLine')
|
|
66
|
-
expect(markup).toContain('+newLine')
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
test('renders delete_file operation', () => {
|
|
70
|
-
const toolBlock = createToolBlock({
|
|
71
|
-
type: 'delete_file',
|
|
72
|
-
path: 'src/remove-me.ts',
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
const result = renderToolComponent(toolBlock, chatThemes.dark, renderOptions)
|
|
76
|
-
|
|
77
|
-
expect(result).toBeDefined()
|
|
78
|
-
expect(result?.content).toBeDefined()
|
|
79
|
-
|
|
80
|
-
const markup = renderToStaticMarkup(result?.content as React.ReactElement)
|
|
81
|
-
expect(markup).toContain('Delete')
|
|
82
|
-
expect(markup).toContain('src/remove-me.ts')
|
|
83
|
-
})
|
|
84
|
-
})
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import { renderToStaticMarkup } from 'react-dom/server'
|
|
4
|
-
|
|
5
|
-
import { initializeThemeStore } from '../../../hooks/use-theme'
|
|
6
|
-
import { CodeSearchComponent } from '../code-search'
|
|
7
|
-
|
|
8
|
-
import type { ChatTheme } from '../../../types/theme-system'
|
|
9
|
-
import type { ToolBlock } from '../types'
|
|
10
|
-
|
|
11
|
-
initializeThemeStore()
|
|
12
|
-
|
|
13
|
-
const createToolBlock = (
|
|
14
|
-
output?: string,
|
|
15
|
-
): ToolBlock & { toolName: 'code_search' } => ({
|
|
16
|
-
type: 'tool',
|
|
17
|
-
toolName: 'code_search',
|
|
18
|
-
toolCallId: 'code-search-test',
|
|
19
|
-
input: {
|
|
20
|
-
pattern: 'getAgentBaseName',
|
|
21
|
-
cwd: 'cli/src/utils',
|
|
22
|
-
},
|
|
23
|
-
output,
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
describe('CodeSearchComponent', () => {
|
|
27
|
-
test('uses formatted match count from current code search output', () => {
|
|
28
|
-
const result = CodeSearchComponent.render(
|
|
29
|
-
createToolBlock(`Found 2 matches
|
|
30
|
-
./message-block-helpers.ts:
|
|
31
|
-
Line 13: export const getAgentBaseName = (type: string): string => {
|
|
32
|
-
Line 196: getAgentBaseName(options.agentType ?? '') === 'code-searcher'`),
|
|
33
|
-
{} as ChatTheme,
|
|
34
|
-
{
|
|
35
|
-
availableWidth: 80,
|
|
36
|
-
indentationOffset: 0,
|
|
37
|
-
labelWidth: 10,
|
|
38
|
-
},
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
const markup = renderToStaticMarkup(<>{result.content}</>)
|
|
42
|
-
|
|
43
|
-
expect(markup).toContain('getAgentBaseName in cli/src/utils (2 results)')
|
|
44
|
-
})
|
|
45
|
-
})
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { getGravityIndexParts } from '../gravity-index'
|
|
4
|
-
|
|
5
|
-
describe('getGravityIndexParts', () => {
|
|
6
|
-
test('describes search queries', () => {
|
|
7
|
-
expect(
|
|
8
|
-
getGravityIndexParts({
|
|
9
|
-
action: 'search',
|
|
10
|
-
query: 'transactional email for a Next.js app',
|
|
11
|
-
}),
|
|
12
|
-
).toEqual({
|
|
13
|
-
name: 'Search services',
|
|
14
|
-
description: 'transactional email for a Next.js app',
|
|
15
|
-
})
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
test('describes browse category and keyword', () => {
|
|
19
|
-
expect(
|
|
20
|
-
getGravityIndexParts({
|
|
21
|
-
action: 'browse',
|
|
22
|
-
category: 'Email',
|
|
23
|
-
q: 'send',
|
|
24
|
-
}),
|
|
25
|
-
).toEqual({
|
|
26
|
-
name: 'Browse services',
|
|
27
|
-
description: 'Email · send',
|
|
28
|
-
})
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
test('describes service detail lookups', () => {
|
|
32
|
-
expect(
|
|
33
|
-
getGravityIndexParts({
|
|
34
|
-
action: 'get_service',
|
|
35
|
-
slug: 'sendgrid',
|
|
36
|
-
}),
|
|
37
|
-
).toEqual({
|
|
38
|
-
name: 'Fetch service',
|
|
39
|
-
description: 'sendgrid',
|
|
40
|
-
})
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
test('describes completed integration reports', () => {
|
|
44
|
-
expect(
|
|
45
|
-
getGravityIndexParts({
|
|
46
|
-
action: 'report_integration',
|
|
47
|
-
integrated_slug: 'sendgrid',
|
|
48
|
-
}),
|
|
49
|
-
).toEqual({
|
|
50
|
-
name: 'Report integration',
|
|
51
|
-
description: 'sendgrid integration',
|
|
52
|
-
})
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
test('names the action even when the target is missing', () => {
|
|
56
|
-
expect(getGravityIndexParts({ action: 'search' })).toEqual({
|
|
57
|
-
name: 'Search services',
|
|
58
|
-
description: '',
|
|
59
|
-
})
|
|
60
|
-
expect(getGravityIndexParts({ action: 'list_categories' })).toEqual({
|
|
61
|
-
name: 'List service categories',
|
|
62
|
-
description: '',
|
|
63
|
-
})
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
test('falls back to the brand for unknown input', () => {
|
|
67
|
-
expect(getGravityIndexParts({ action: 'unknown' })).toEqual({
|
|
68
|
-
name: 'Services',
|
|
69
|
-
description: '',
|
|
70
|
-
})
|
|
71
|
-
expect(getGravityIndexParts(null)).toEqual({
|
|
72
|
-
name: 'Services',
|
|
73
|
-
description: '',
|
|
74
|
-
})
|
|
75
|
-
})
|
|
76
|
-
})
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import { renderToStaticMarkup } from 'react-dom/server'
|
|
4
|
-
|
|
5
|
-
import { initializeThemeStore } from '../../../hooks/use-theme'
|
|
6
|
-
import { chatThemes } from '../../../utils/theme-system'
|
|
7
|
-
import { RenderUIComponent } from '../render-ui'
|
|
8
|
-
|
|
9
|
-
import type { ToolBlock } from '../types'
|
|
10
|
-
|
|
11
|
-
initializeThemeStore()
|
|
12
|
-
|
|
13
|
-
const createToolBlock = (
|
|
14
|
-
input: unknown,
|
|
15
|
-
): ToolBlock & { toolName: 'render_ui' } => ({
|
|
16
|
-
type: 'tool',
|
|
17
|
-
toolName: 'render_ui',
|
|
18
|
-
toolCallId: 'test-render-ui-call-id',
|
|
19
|
-
input,
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
describe('RenderUIComponent', () => {
|
|
23
|
-
test('renders a button widget', () => {
|
|
24
|
-
const result = RenderUIComponent.render(
|
|
25
|
-
createToolBlock({
|
|
26
|
-
widget: {
|
|
27
|
-
type: 'button',
|
|
28
|
-
text: 'Open preview',
|
|
29
|
-
link: 'https://example.com/preview',
|
|
30
|
-
variant: 'primary',
|
|
31
|
-
},
|
|
32
|
-
}),
|
|
33
|
-
chatThemes.light,
|
|
34
|
-
{
|
|
35
|
-
availableWidth: 80,
|
|
36
|
-
indentationOffset: 0,
|
|
37
|
-
labelWidth: 10,
|
|
38
|
-
},
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
expect(result.collapsedPreview).toBe(
|
|
42
|
-
'Open preview -> https://example.com/preview',
|
|
43
|
-
)
|
|
44
|
-
expect(result.content).toBeDefined()
|
|
45
|
-
expect(renderToStaticMarkup(<>{result.content}</>)).toContain(
|
|
46
|
-
'Open preview',
|
|
47
|
-
)
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
test('does not render an unresolved Gravity reference', () => {
|
|
51
|
-
const result = RenderUIComponent.render(
|
|
52
|
-
createToolBlock({
|
|
53
|
-
widget: {
|
|
54
|
-
type: 'button',
|
|
55
|
-
text: 'Get your Resend API key',
|
|
56
|
-
link: {
|
|
57
|
-
source: 'gravity_index',
|
|
58
|
-
search_id: 'search-1',
|
|
59
|
-
service_slug: 'resend',
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
}),
|
|
63
|
-
chatThemes.light,
|
|
64
|
-
{
|
|
65
|
-
availableWidth: 80,
|
|
66
|
-
indentationOffset: 0,
|
|
67
|
-
labelWidth: 10,
|
|
68
|
-
},
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
expect(result.content).toBeNull()
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
test('returns no content for unsupported widgets', () => {
|
|
75
|
-
const result = RenderUIComponent.render(
|
|
76
|
-
createToolBlock({
|
|
77
|
-
widget: {
|
|
78
|
-
type: 'slider',
|
|
79
|
-
text: 'Volume',
|
|
80
|
-
},
|
|
81
|
-
}),
|
|
82
|
-
chatThemes.light,
|
|
83
|
-
{
|
|
84
|
-
availableWidth: 80,
|
|
85
|
-
indentationOffset: 0,
|
|
86
|
-
labelWidth: 10,
|
|
87
|
-
},
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
expect(result.content).toBeNull()
|
|
91
|
-
})
|
|
92
|
-
})
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test'
|
|
2
|
-
|
|
3
|
-
import { parseTerminalOutput, RunTerminalCommandComponent } from '../run-terminal-command'
|
|
4
|
-
|
|
5
|
-
import type { ChatTheme } from '../../../types/theme-system'
|
|
6
|
-
import type { ToolBlock } from '../types'
|
|
7
|
-
import type { ReactElement } from 'react'
|
|
8
|
-
|
|
9
|
-
// Use ChatTheme import for proper typing
|
|
10
|
-
|
|
11
|
-
// Type for the render result content element
|
|
12
|
-
interface RenderContentElement extends ReactElement {
|
|
13
|
-
props: {
|
|
14
|
-
timeoutSeconds?: number
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Helper to create a mock tool block
|
|
19
|
-
const createToolBlock = (
|
|
20
|
-
command: string,
|
|
21
|
-
output?: string,
|
|
22
|
-
timeoutSeconds?: number,
|
|
23
|
-
): ToolBlock & { toolName: 'run_terminal_command' } => ({
|
|
24
|
-
type: 'tool',
|
|
25
|
-
toolName: 'run_terminal_command',
|
|
26
|
-
toolCallId: 'test-tool-call-id',
|
|
27
|
-
input: { command, ...(timeoutSeconds !== undefined && { timeout_seconds: timeoutSeconds }) },
|
|
28
|
-
output,
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
// Helper to create JSON output in the format the component expects
|
|
32
|
-
const createJsonOutput = (stdout: string, stderr = ''): string => {
|
|
33
|
-
return JSON.stringify([
|
|
34
|
-
{
|
|
35
|
-
type: 'json',
|
|
36
|
-
value: {
|
|
37
|
-
command: 'test',
|
|
38
|
-
stdout,
|
|
39
|
-
stderr,
|
|
40
|
-
exitCode: 0,
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
])
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
describe('RunTerminalCommandComponent', () => {
|
|
47
|
-
describe('render', () => {
|
|
48
|
-
test('returns content and collapsedPreview', () => {
|
|
49
|
-
const toolBlock = createToolBlock('ls -la', createJsonOutput('file1\nfile2'))
|
|
50
|
-
const mockTheme = {} as ChatTheme
|
|
51
|
-
const mockOptions = {
|
|
52
|
-
availableWidth: 80,
|
|
53
|
-
indentationOffset: 0,
|
|
54
|
-
labelWidth: 10,
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const result = RunTerminalCommandComponent.render(toolBlock, mockTheme, mockOptions)
|
|
58
|
-
|
|
59
|
-
expect(result).toBeDefined()
|
|
60
|
-
expect(result.content).toBeDefined()
|
|
61
|
-
expect(result.collapsedPreview).toBe('$ ls -la')
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
test('preserves leading whitespace in stdout (tree output)', () => {
|
|
65
|
-
// Simulate tree command output with leading spaces for indentation
|
|
66
|
-
const treeOutput = `├── src
|
|
67
|
-
│ ├── index.ts
|
|
68
|
-
│ └── utils
|
|
69
|
-
│ └── helper.ts
|
|
70
|
-
└── package.json`
|
|
71
|
-
|
|
72
|
-
const { output } = parseTerminalOutput(createJsonOutput(treeOutput))
|
|
73
|
-
|
|
74
|
-
expect(output).toBe(treeOutput)
|
|
75
|
-
// Verify leading characters are preserved (├ has no leading space, but indented lines do)
|
|
76
|
-
expect(output?.startsWith('├')).toBe(true)
|
|
77
|
-
expect(output).toContain('│ ├')
|
|
78
|
-
expect(output).toContain('│ └')
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
test('preserves leading spaces in table-like output', () => {
|
|
82
|
-
// Simulate output with leading spaces for alignment
|
|
83
|
-
const tableOutput = ` Name Size Modified
|
|
84
|
-
file1.txt 1.2KB 2024-01-15
|
|
85
|
-
file2.txt 3.4MB 2024-01-16`
|
|
86
|
-
|
|
87
|
-
const { output } = parseTerminalOutput(createJsonOutput(tableOutput))
|
|
88
|
-
|
|
89
|
-
expect(output).toBe(tableOutput)
|
|
90
|
-
// Verify leading spaces are preserved
|
|
91
|
-
expect(output?.startsWith(' ')).toBe(true)
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
test('preserves leading spaces in indented code output', () => {
|
|
95
|
-
// Simulate indented output like grep with context
|
|
96
|
-
const indentedOutput = ` function hello() {
|
|
97
|
-
console.log("world")
|
|
98
|
-
}`
|
|
99
|
-
|
|
100
|
-
const { output } = parseTerminalOutput(createJsonOutput(indentedOutput))
|
|
101
|
-
|
|
102
|
-
expect(output).toBe(indentedOutput)
|
|
103
|
-
expect(output?.startsWith(' ')).toBe(true)
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
test('removes trailing whitespace while preserving leading whitespace', () => {
|
|
107
|
-
const outputWithTrailing = ' leading preserved\ntrailing removed \n\n'
|
|
108
|
-
const expectedOutput = ' leading preserved\ntrailing removed'
|
|
109
|
-
|
|
110
|
-
const { output } = parseTerminalOutput(createJsonOutput(outputWithTrailing))
|
|
111
|
-
|
|
112
|
-
expect(output).toBe(expectedOutput)
|
|
113
|
-
// Leading spaces preserved
|
|
114
|
-
expect(output?.startsWith(' ')).toBe(true)
|
|
115
|
-
// Trailing whitespace removed
|
|
116
|
-
expect(output?.endsWith('removed')).toBe(true)
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
test('handles raw string output (non-JSON) and preserves leading whitespace', () => {
|
|
120
|
-
const rawOutput = ' indented raw output'
|
|
121
|
-
const { output } = parseTerminalOutput(rawOutput)
|
|
122
|
-
|
|
123
|
-
expect(output).toBe(rawOutput)
|
|
124
|
-
expect(output?.startsWith(' ')).toBe(true)
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
test('handles combined stdout and stderr with leading whitespace', () => {
|
|
128
|
-
const stdout = ' stdout with leading space\n'
|
|
129
|
-
const stderr = ' stderr with leading space'
|
|
130
|
-
|
|
131
|
-
const { output } = parseTerminalOutput(
|
|
132
|
-
JSON.stringify([
|
|
133
|
-
{
|
|
134
|
-
type: 'json',
|
|
135
|
-
value: { stdout, stderr, exitCode: 0 },
|
|
136
|
-
},
|
|
137
|
-
]),
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
expect(output).toContain(' stdout with leading space')
|
|
141
|
-
expect(output).toContain(' stderr with leading space')
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
test('handles output that is only whitespace', () => {
|
|
145
|
-
const whitespaceOnly = ' '
|
|
146
|
-
const { output } = parseTerminalOutput(createJsonOutput(whitespaceOnly))
|
|
147
|
-
|
|
148
|
-
// trimEnd() on whitespace-only string returns empty string, which becomes null
|
|
149
|
-
expect(output).toBe(null)
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
test('handles empty output', () => {
|
|
153
|
-
const { output } = parseTerminalOutput(createJsonOutput(''))
|
|
154
|
-
|
|
155
|
-
expect(output).toBe(null)
|
|
156
|
-
})
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
describe('timeout extraction', () => {
|
|
160
|
-
const mockTheme = {} as ChatTheme
|
|
161
|
-
const mockOptions = {
|
|
162
|
-
availableWidth: 80,
|
|
163
|
-
indentationOffset: 0,
|
|
164
|
-
labelWidth: 10,
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
test('passes undefined timeoutSeconds when timeout_seconds not provided', () => {
|
|
168
|
-
const toolBlock = createToolBlock('ls -la', createJsonOutput('output'))
|
|
169
|
-
|
|
170
|
-
const result = RunTerminalCommandComponent.render(toolBlock, mockTheme, mockOptions)
|
|
171
|
-
|
|
172
|
-
expect((result.content as RenderContentElement).props.timeoutSeconds).toBeUndefined()
|
|
173
|
-
})
|
|
174
|
-
|
|
175
|
-
test('passes timeoutSeconds for positive timeout', () => {
|
|
176
|
-
const toolBlock = createToolBlock('npm test', createJsonOutput('tests passed'), 60)
|
|
177
|
-
|
|
178
|
-
const result = RunTerminalCommandComponent.render(toolBlock, mockTheme, mockOptions)
|
|
179
|
-
|
|
180
|
-
expect((result.content as RenderContentElement).props.timeoutSeconds).toBe(60)
|
|
181
|
-
})
|
|
182
|
-
|
|
183
|
-
test('passes timeoutSeconds for no timeout (-1)', () => {
|
|
184
|
-
const toolBlock = createToolBlock('long-running-task', createJsonOutput('done'), -1)
|
|
185
|
-
|
|
186
|
-
const result = RunTerminalCommandComponent.render(toolBlock, mockTheme, mockOptions)
|
|
187
|
-
|
|
188
|
-
expect((result.content as RenderContentElement).props.timeoutSeconds).toBe(-1)
|
|
189
|
-
})
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
describe('parseTerminalOutput', () => {
|
|
193
|
-
test('handles error messages', () => {
|
|
194
|
-
const errorPayload = JSON.stringify([
|
|
195
|
-
{
|
|
196
|
-
type: 'json',
|
|
197
|
-
value: {
|
|
198
|
-
command: 'test',
|
|
199
|
-
errorMessage: 'Something went wrong',
|
|
200
|
-
stdout: '',
|
|
201
|
-
stderr: '',
|
|
202
|
-
exitCode: 1,
|
|
203
|
-
},
|
|
204
|
-
},
|
|
205
|
-
])
|
|
206
|
-
|
|
207
|
-
const { output, startingCwd } = parseTerminalOutput(errorPayload)
|
|
208
|
-
|
|
209
|
-
expect(output).toBe('Error: Something went wrong')
|
|
210
|
-
expect(startingCwd).toBeUndefined()
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
test('extracts startingCwd when present', () => {
|
|
214
|
-
const payloadWithCwd = JSON.stringify([
|
|
215
|
-
{
|
|
216
|
-
type: 'json',
|
|
217
|
-
value: {
|
|
218
|
-
command: 'pwd',
|
|
219
|
-
stdout: '/project\n',
|
|
220
|
-
stderr: '',
|
|
221
|
-
exitCode: 0,
|
|
222
|
-
startingCwd: '/project',
|
|
223
|
-
},
|
|
224
|
-
},
|
|
225
|
-
])
|
|
226
|
-
|
|
227
|
-
const { output, startingCwd } = parseTerminalOutput(payloadWithCwd)
|
|
228
|
-
|
|
229
|
-
expect(output).toBe('/project')
|
|
230
|
-
expect(startingCwd).toBe('/project')
|
|
231
|
-
})
|
|
232
|
-
})
|
|
233
|
-
})
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test'
|
|
2
|
-
import { createTestRenderer } from '@opentui/core/testing'
|
|
3
|
-
import { createRoot, flushSync } from '@opentui/react'
|
|
4
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
5
|
-
import React, { useEffect, useState } from 'react'
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
ChatRuntimeProvider,
|
|
9
|
-
useChatRuntime,
|
|
10
|
-
type ChatRuntime,
|
|
11
|
-
} from '../chat-runtime-context'
|
|
12
|
-
import {
|
|
13
|
-
registerActiveRun,
|
|
14
|
-
stopActiveRun,
|
|
15
|
-
type ActiveRunStopReason,
|
|
16
|
-
} from '../../utils/active-run'
|
|
17
|
-
|
|
18
|
-
import type { StreamStatus } from '../../hooks/use-message-queue'
|
|
19
|
-
|
|
20
|
-
describe('ChatRuntimeProvider navigation', () => {
|
|
21
|
-
for (const phase of ['waiting', 'streaming'] satisfies StreamStatus[]) {
|
|
22
|
-
test(`preserves ${phase} runtime while visiting chat history`, async () => {
|
|
23
|
-
let runtime: ChatRuntime | undefined
|
|
24
|
-
let setShowHistory: ((show: boolean) => void) | undefined
|
|
25
|
-
let chatUnmounts = 0
|
|
26
|
-
|
|
27
|
-
const RuntimeSnapshot = ({ screen }: { screen: 'chat' | 'history' }) => {
|
|
28
|
-
runtime = useChatRuntime()
|
|
29
|
-
return (
|
|
30
|
-
<text>{`${screen}:${runtime.streamStatus}:${runtime.queuedMessages.length}`}</text>
|
|
31
|
-
)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// These must remain distinct component types: production routing
|
|
35
|
-
// unmounts Chat and mounts ChatHistoryScreen rather than updating props
|
|
36
|
-
// on one shared view component.
|
|
37
|
-
const ChatView = () => {
|
|
38
|
-
useEffect(
|
|
39
|
-
() => () => {
|
|
40
|
-
chatUnmounts++
|
|
41
|
-
},
|
|
42
|
-
[],
|
|
43
|
-
)
|
|
44
|
-
return <RuntimeSnapshot screen="chat" />
|
|
45
|
-
}
|
|
46
|
-
const HistoryView = () => <RuntimeSnapshot screen="history" />
|
|
47
|
-
|
|
48
|
-
const HistoryRouter = () => {
|
|
49
|
-
const [showHistory, setHistory] = useState(false)
|
|
50
|
-
setShowHistory = setHistory
|
|
51
|
-
return showHistory ? <HistoryView /> : <ChatView />
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const setup = await createTestRenderer({ width: 80, height: 3 })
|
|
55
|
-
const root = createRoot(setup.renderer)
|
|
56
|
-
const queryClient = new QueryClient({
|
|
57
|
-
defaultOptions: { queries: { retry: false } },
|
|
58
|
-
})
|
|
59
|
-
const inputRef = { current: null }
|
|
60
|
-
flushSync(() => {
|
|
61
|
-
root.render(
|
|
62
|
-
<QueryClientProvider client={queryClient}>
|
|
63
|
-
<ChatRuntimeProvider inputRef={inputRef} continueChat={false}>
|
|
64
|
-
<HistoryRouter />
|
|
65
|
-
</ChatRuntimeProvider>
|
|
66
|
-
</QueryClientProvider>,
|
|
67
|
-
)
|
|
68
|
-
})
|
|
69
|
-
await setup.renderOnce()
|
|
70
|
-
|
|
71
|
-
try {
|
|
72
|
-
expect(runtime).toBeDefined()
|
|
73
|
-
const stopReasons: ActiveRunStopReason[] = []
|
|
74
|
-
registerActiveRun('navigation-test', (reason) => {
|
|
75
|
-
stopReasons.push(reason)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
flushSync(() => {
|
|
79
|
-
runtime!.isChainInProgressRef.current = true
|
|
80
|
-
runtime!.setStreamStatus(phase)
|
|
81
|
-
runtime!.mainAgentTimer.start()
|
|
82
|
-
runtime!.addToQueue('keep me queued')
|
|
83
|
-
})
|
|
84
|
-
await setup.renderOnce()
|
|
85
|
-
|
|
86
|
-
const timerStartTime = runtime!.timerStartTime
|
|
87
|
-
const sendMessage = runtime!.sendMessage
|
|
88
|
-
expect(timerStartTime).not.toBeNull()
|
|
89
|
-
expect(setup.captureCharFrame()).toContain(`chat:${phase}:1`)
|
|
90
|
-
|
|
91
|
-
flushSync(() => setShowHistory!(true))
|
|
92
|
-
await setup.renderOnce()
|
|
93
|
-
|
|
94
|
-
expect(setup.captureCharFrame()).toContain(`history:${phase}:1`)
|
|
95
|
-
expect(chatUnmounts).toBe(1)
|
|
96
|
-
expect(runtime!.timerStartTime).toBe(timerStartTime)
|
|
97
|
-
expect(runtime!.sendMessage).toBe(sendMessage)
|
|
98
|
-
|
|
99
|
-
flushSync(() => setShowHistory!(false))
|
|
100
|
-
await setup.renderOnce()
|
|
101
|
-
|
|
102
|
-
expect(setup.captureCharFrame()).toContain(`chat:${phase}:1`)
|
|
103
|
-
expect(runtime!.timerStartTime).toBe(timerStartTime)
|
|
104
|
-
expect(runtime!.sendMessage).toBe(sendMessage)
|
|
105
|
-
let stoppedRun = false
|
|
106
|
-
flushSync(() => {
|
|
107
|
-
stoppedRun = stopActiveRun('user-interrupt')
|
|
108
|
-
})
|
|
109
|
-
expect(stoppedRun).toBe(true)
|
|
110
|
-
expect(stopReasons).toEqual(['user-interrupt'])
|
|
111
|
-
await setup.renderOnce()
|
|
112
|
-
expect(runtime!.queuePaused).toBe(true)
|
|
113
|
-
expect(runtime!.queuedMessages).toHaveLength(1)
|
|
114
|
-
|
|
115
|
-
// A queue add and interrupt can occur before React renders again.
|
|
116
|
-
// The synchronous queue ref must still make the interrupt pause it.
|
|
117
|
-
flushSync(() => {
|
|
118
|
-
runtime!.clearQueue()
|
|
119
|
-
runtime!.resumeQueue()
|
|
120
|
-
registerActiveRun('same-tick-test', (reason) => {
|
|
121
|
-
stopReasons.push(reason)
|
|
122
|
-
})
|
|
123
|
-
runtime!.addToQueue('queued in the interrupt tick')
|
|
124
|
-
stoppedRun = stopActiveRun('user-interrupt')
|
|
125
|
-
})
|
|
126
|
-
expect(stoppedRun).toBe(true)
|
|
127
|
-
await setup.renderOnce()
|
|
128
|
-
expect(runtime!.queuePaused).toBe(true)
|
|
129
|
-
expect(runtime!.queuedMessages).toHaveLength(1)
|
|
130
|
-
expect(stopReasons).toEqual(['user-interrupt', 'user-interrupt'])
|
|
131
|
-
|
|
132
|
-
// Context changes still clean a paused queue after the run owner has
|
|
133
|
-
// already been released.
|
|
134
|
-
flushSync(() => {
|
|
135
|
-
stoppedRun = stopActiveRun('new-chat')
|
|
136
|
-
})
|
|
137
|
-
expect(stoppedRun).toBe(false)
|
|
138
|
-
await setup.renderOnce()
|
|
139
|
-
expect(runtime!.queuedMessages).toHaveLength(0)
|
|
140
|
-
expect(runtime!.queuePaused).toBe(false)
|
|
141
|
-
} finally {
|
|
142
|
-
stopActiveRun('process-exit')
|
|
143
|
-
flushSync(() => root.unmount())
|
|
144
|
-
queryClient.clear()
|
|
145
|
-
setup.renderer.destroy()
|
|
146
|
-
}
|
|
147
|
-
})
|
|
148
|
-
}
|
|
149
|
-
})
|