Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Touchups for pr tool calling #1647

Merged
merged 1 commit into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 28 additions & 31 deletions assets/src/components/ai/chatbot/AISuggestFix.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { Button, Markdown, PrOpenIcon, Toast } from '@pluralsh/design-system'
import {
Button,
LinkoutIcon,
Markdown,
PrOpenIcon,
Toast,
} from '@pluralsh/design-system'
import {
Dispatch,
ReactNode,
Expand All @@ -8,7 +14,6 @@ import {
useRef,
useState,
} from 'react'
import { useTheme } from 'styled-components'
import {
AiDelta,
AiInsightFragment,
Expand Down Expand Up @@ -87,37 +92,15 @@ function FixPr({
const [mutation, { data, loading, error }] = useAiFixPrMutation({
variables: { insightId, messages: [{ role: AiRole.User, content: fix }] },
})
const theme = useTheme()

// TEMP FIX, implement permanent solution in DS
const successToastRef = useRef<HTMLDivElement>(null)
const errorToastRef = useRef<HTMLDivElement>(null)
useEffect(() => {
if (successToastRef.current) successToastRef.current.style.zIndex = '10000'
if (errorToastRef.current) errorToastRef.current.style.zIndex = '10000'
}, [data?.aiFixPr])

return (
<>
{data?.aiFixPr && (
<Toast
ref={successToastRef}
severity="info"
position="top-right"
margin="large"
heading="PR Created!"
>
<a
href={data?.aiFixPr?.url}
target="_blank"
rel="noreferrer"
style={{ textDecoration: 'none', cursor: 'pointer' }}
color={theme.colors['action-link-inline']}
>
{data?.aiFixPr?.url}
</a>
</Toast>
)}
{error && (
<Toast
ref={errorToastRef}
Expand All @@ -129,13 +112,27 @@ function FixPr({
{error.message}
</Toast>
)}
<Button
startIcon={<PrOpenIcon />}
onClick={mutation}
loading={loading}
>
Open PR
</Button>
{data?.aiFixPr ? (
<Button
primary
type="button"
endIcon={<LinkoutIcon />}
as="a"
href={data?.aiFixPr?.url}
target="_blank"
rel="noopener noreferrer"
>
View PR
</Button>
) : (
<Button
startIcon={<PrOpenIcon />}
onClick={mutation}
loading={loading}
>
Create PR
</Button>
)}
</>
)
}
Expand Down
26 changes: 22 additions & 4 deletions assets/src/components/cd/cluster/ClusterInsightComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { stringify } from 'yaml'
import {
AiInsight,
ClusterInsightComponent as ClusterInsightComponentAPI,
useClusterInsightComponentQuery,
} from '../../../generated/graphql.ts'
import {
CLUSTER_ABS_PATH,
Expand All @@ -26,16 +27,20 @@ import {
useSetNavigationContent,
} from './ClusterInsights.tsx'
import { ComponentEntry } from './ClusterInsightsComponents.tsx'
import LoadingIndicator from 'components/utils/LoadingIndicator.tsx'
import { GqlError } from 'components/utils/Alert.tsx'

export default function ClusterInsightComponent(): ReactNode {
const theme = useTheme()
const { cluster, clusterLoading, refetch } = useClusterInsightsContext()
const id =
useMatch(`${CLUSTER_ABS_PATH}/${CLUSTER_INSIGHTS_PATH}/components/:id`)
?.params?.id || ''
const component = cluster.insightComponents?.find(
(cmp) => cmp?.id === id
) as ClusterInsightComponentAPI
const { data, loading, error } = useClusterInsightComponentQuery({
variables: { id },
})

const component = data?.clusterInsightComponent
const [showRaw, setShowRaw] = useState(false)

useSetNavigationContent(
Expand Down Expand Up @@ -67,7 +72,7 @@ export default function ClusterInsightComponent(): ReactNode {
{cluster?.name}
</BasicLink>
<ComponentEntry
component={component}
component={component as Nullable<ClusterInsightComponentAPI>}
icon={null}
/>
</Flex>
Expand Down Expand Up @@ -102,6 +107,19 @@ export default function ClusterInsightComponent(): ReactNode {
)
)

if (error) {
return (
<GqlError
error={error}
header="Error loading insight component"
/>
)
}

if (loading) {
return <LoadingIndicator />
}

return (
<>
<Divider backgroundColor={theme.colors.border} />
Expand Down
2 changes: 1 addition & 1 deletion assets/src/generated/graphql-kubernetes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable */
/* prettier-ignore */
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
Expand Down
2 changes: 1 addition & 1 deletion assets/src/generated/graphql-plural.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable */
/* prettier-ignore */
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
Expand Down
135 changes: 108 additions & 27 deletions assets/src/generated/graphql.ts

Large diffs are not rendered by default.

16 changes: 13 additions & 3 deletions assets/src/graph/ai.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,18 @@ fragment ClusterInsightComponent on ClusterInsightComponent {
namespace
group
version
resource {
raw
}
insight {
...AiInsight
}
}

fragment ClusterInsightComponentDetail on ClusterInsightComponent {
...ClusterInsightComponent
resource {
raw
}
}

fragment AiPin on AiPin {
id
name
Expand Down Expand Up @@ -198,6 +202,12 @@ query ChatThreadDetails($id: ID!) {
}
}

query ClusterInsightComponent($id: ID!) {
clusterInsightComponent(id: $id) {
...ClusterInsightComponentDetail
}
}

mutation CreateAIPin($attributes: AiPinAttributes!) {
createPin(attributes: $attributes) {
...AiPin
Expand Down
21 changes: 16 additions & 5 deletions assets/src/helpers/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ export const authlessClient = new ApolloClient({
})

function maybeReconnect(socket, absintheSocket) {
console.warn('socket reconnect attempt', socket)
const chan = absintheSocket.channel
console.log('socket reconnect attempt', socket)
if (socket.connectionState() === 'closed') {
console.warn('found dead websocket, attempting a reconnect')
if (!socket.conn) {
Expand All @@ -37,12 +38,18 @@ function maybeReconnect(socket, absintheSocket) {
socket.reconnectTimer.scheduleTimeout()
}

absintheSocket.channel.rejoin()
absintheSocket.channel.rejoinTimer.scheduleTimeout()
return
}

console.warn('socket not dead, ignoring')
const state = chan.state
if (state === 'closed' || state === 'errored') {
console.log('broken absinthe channel, rejoining')
chan.rejoin()
return
}

console.log('found healthy channel', chan)
console.log('absinthe socket not dead, ignoring')
}

export function buildClient(gqlUrl, wsUrl, fetchToken) {
Expand Down Expand Up @@ -77,6 +84,10 @@ export function buildClient(gqlUrl, wsUrl, fetchToken) {
const socketLink = createAbsintheSocketLink(absintheSocket)
const gqlLink = errorLink.concat(httpLink)

absintheSocket.channel.onClose(() => {
absintheSocket.channel.rejoin()
})

const splitLink = split(
(operation) => hasSubscription(operation.query),
socketLink,
Expand Down Expand Up @@ -105,7 +116,7 @@ export function buildClient(gqlUrl, wsUrl, fetchToken) {
})

socket.onClose(() => maybeReconnect(socket, absintheSocket))
setInterval(() => maybeReconnect(socket, absintheSocket), 10000)
setInterval(() => maybeReconnect(socket, absintheSocket), 5000)

return { client, socket }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ spec:
- key
type: object
x-kubernetes-map-type: atomic
toolModel:
description: Model to use for tool calling, which is less
frequent and often requires more advanced reasoning
type: string
required:
- tokenSecretRef
type: object
Expand Down Expand Up @@ -122,6 +126,10 @@ spec:
- key
type: object
x-kubernetes-map-type: atomic
toolModel:
description: Model to use for tool calling, which is less
frequent and often requires more advanced reasoning
type: string
required:
- endpoint
- tokenSecretRef
Expand Down Expand Up @@ -158,6 +166,10 @@ spec:
- key
type: object
x-kubernetes-map-type: atomic
toolModelId:
description: Model to use for tool calling, which is less
frequent and often requires more advanced reasoning
type: string
required:
- modelId
type: object
Expand Down Expand Up @@ -196,6 +208,10 @@ spec:
- key
type: object
x-kubernetes-map-type: atomic
toolModel:
description: Model to use for tool calling, which is less
frequent and often requires more advanced reasoning
type: string
url:
description: URL is the url this model is queryable on
type: string
Expand Down Expand Up @@ -236,6 +252,10 @@ spec:
- key
type: object
x-kubernetes-map-type: atomic
toolModel:
description: Model to use for tool calling, which is less
frequent and often requires more advanced reasoning
type: string
required:
- tokenSecretRef
type: object
Expand Down Expand Up @@ -288,6 +308,10 @@ spec:
- key
type: object
x-kubernetes-map-type: atomic
toolModel:
description: Model to use for tool calling, which is less
frequent and often requires more advanced reasoning
type: string
required:
- location
- project
Expand Down
Loading
Loading