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

[inference] Add cancelation support for chatComplete and output #203108

Merged
merged 13 commits into from
Dec 17, 2024

Conversation

pgayvallet
Copy link
Contributor

@pgayvallet pgayvallet commented Dec 5, 2024

Summary

Fix #200757

Add cancelation support for chatComplete and output, based on an abort signal.

Examples

response mode

import { isInferenceRequestAbortedError } from '@kbn/inference-common';

try {
  const abortController = new AbortController();
  const chatResponse = await inferenceClient.chatComplete({
    connectorId: 'some-gen-ai-connector',
    abortSignal: abortController.signal,
    messages: [{ role: MessageRole.User, content: 'Do something' }],
  });
} catch(e) {
  if(isInferenceRequestAbortedError(e)) {
    // request was aborted, do something
  } else {
    // was another error, do something else
  }
}

// elsewhere
abortController.abort()

stream mode

import { isInferenceRequestAbortedError } from '@kbn/inference-common';

const abortController = new AbortController();
const events$ = inferenceClient.chatComplete({
  stream: true,
  connectorId: 'some-gen-ai-connector',
  abortSignal: abortController.signal,
  messages: [{ role: MessageRole.User, content: 'Do something' }],
});

events$.subscribe({
  next: (event) => {
    // do something
  },
  error: (err) => {
    if(isInferenceRequestAbortedError(e)) {
      // request was aborted, do something
    } else {
      // was another error, do something else
    }
  }
});

abortController.abort();

@pgayvallet
Copy link
Contributor Author

/ci

@pgayvallet
Copy link
Contributor Author

/ci

@pgayvallet
Copy link
Contributor Author

/ci

@pgayvallet pgayvallet added release_note:skip Skip the PR/issue when compiling release notes backport:version Backport to applied version labels Team:AI Infra AppEx AI Infrastructure Team v8.18.0 labels Dec 11, 2024
@pgayvallet
Copy link
Contributor Author

/ci

@pgayvallet pgayvallet marked this pull request as ready for review December 11, 2024 14:57
@pgayvallet pgayvallet requested a review from a team as a code owner December 11, 2024 14:57
@elasticmachine
Copy link
Contributor

Pinging @elastic/appex-ai-infra (Team:AI Infra)

Copy link
Member

@legrego legrego left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

},
complete: () => {
if (abortSignal.aborted) {
subscriber.error(createInferenceRequestAbortedError('Request was aborted'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question What other messages do we envision for these aborted request errors? This is the only place it's called today, and we pass in a hard-coded message.

I am not asking you to change this, I'm just curious if you have thoughts about the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's a fair point. We probably don't need that message to be passed as a parameter to be honest. I was mostly following the pattern that was used for other inference error types. I will change that

source$.next(3);

expect(values).toEqual([1, 2]);
expect(thrownError).toBeDefined();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should we assert the correct error instance is thrown?

Suggested change
expect(thrownError).toBeDefined();
expect(thrownError).toBeInstanceOf(InferenceTaskError);
expect(thrownError.code).toBe('requestAborted');

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
@kbn/inference-common 43 40 -3

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
inference 7.4KB 7.5KB +74.0B
Unknown metric groups

API count

id before after diff
@kbn/inference-common 136 141 +5

History

@pgayvallet pgayvallet merged commit 0b74f62 into elastic:main Dec 17, 2024
8 checks passed
@kibanamachine
Copy link
Contributor

Starting backport for target branches: 8.x

https://github.com/elastic/kibana/actions/runs/12375857143

kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Dec 17, 2024
…tic#203108)

## Summary

Fix elastic#200757

Add cancelation support for `chatComplete` and `output`, based on an
abort signal.

### Examples

#### response mode

```ts
import { isInferenceRequestAbortedError } from '@kbn/inference-common';

try {
  const abortController = new AbortController();
  const chatResponse = await inferenceClient.chatComplete({
    connectorId: 'some-gen-ai-connector',
    abortSignal: abortController.signal,
    messages: [{ role: MessageRole.User, content: 'Do something' }],
  });
} catch(e) {
  if(isInferenceRequestAbortedError(e)) {
    // request was aborted, do something
  } else {
    // was another error, do something else
  }
}

// elsewhere
abortController.abort()
```

#### stream mode

```ts
import { isInferenceRequestAbortedError } from '@kbn/inference-common';

const abortController = new AbortController();
const events$ = inferenceClient.chatComplete({
  stream: true,
  connectorId: 'some-gen-ai-connector',
  abortSignal: abortController.signal,
  messages: [{ role: MessageRole.User, content: 'Do something' }],
});

events$.subscribe({
  next: (event) => {
    // do something
  },
  error: (err) => {
    if(isInferenceRequestAbortedError(e)) {
      // request was aborted, do something
    } else {
      // was another error, do something else
    }
  }
});

abortController.abort();
```

(cherry picked from commit 0b74f62)
@kibanamachine
Copy link
Contributor

💚 All backports created successfully

Status Branch Result
8.x

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

stephmilovic pushed a commit that referenced this pull request Dec 17, 2024
…#203108) (#204588)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[inference] Add cancelation support for chatComplete and output
(#203108)](#203108)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Pierre
Gayvallet","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-12-17T15:13:17Z","message":"[inference]
Add cancelation support for chatComplete and output (#203108)\n\n##
Summary\r\n\r\nFix
https://github.com/elastic/kibana/issues/200757\r\n\r\nAdd cancelation
support for `chatComplete` and `output`, based on an\r\nabort
signal.\r\n\r\n\r\n### Examples\r\n\r\n#### response
mode\r\n\r\n```ts\r\nimport { isInferenceRequestAbortedError } from
'@kbn/inference-common';\r\n\r\ntry {\r\n const abortController = new
AbortController();\r\n const chatResponse = await
inferenceClient.chatComplete({\r\n connectorId:
'some-gen-ai-connector',\r\n abortSignal: abortController.signal,\r\n
messages: [{ role: MessageRole.User, content: 'Do something' }],\r\n
});\r\n} catch(e) {\r\n if(isInferenceRequestAbortedError(e)) {\r\n //
request was aborted, do something\r\n } else {\r\n // was another error,
do something else\r\n }\r\n}\r\n\r\n//
elsewhere\r\nabortController.abort()\r\n```\r\n\r\n#### stream
mode\r\n\r\n```ts\r\nimport { isInferenceRequestAbortedError } from
'@kbn/inference-common';\r\n\r\nconst abortController = new
AbortController();\r\nconst events$ = inferenceClient.chatComplete({\r\n
stream: true,\r\n connectorId: 'some-gen-ai-connector',\r\n abortSignal:
abortController.signal,\r\n messages: [{ role: MessageRole.User,
content: 'Do something' }],\r\n});\r\n\r\nevents$.subscribe({\r\n next:
(event) => {\r\n // do something\r\n },\r\n error: (err) => {\r\n
if(isInferenceRequestAbortedError(e)) {\r\n // request was aborted, do
something\r\n } else {\r\n // was another error, do something else\r\n
}\r\n
}\r\n});\r\n\r\nabortController.abort();\r\n```","sha":"0b74f62a338fe1f6b281a019e71279f0d2ffb81f","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","backport:version","Team:AI
Infra","v8.18.0"],"title":"[inference] Add cancelation support for
chatComplete and
output","number":203108,"url":"https://github.com/elastic/kibana/pull/203108","mergeCommit":{"message":"[inference]
Add cancelation support for chatComplete and output (#203108)\n\n##
Summary\r\n\r\nFix
https://github.com/elastic/kibana/issues/200757\r\n\r\nAdd cancelation
support for `chatComplete` and `output`, based on an\r\nabort
signal.\r\n\r\n\r\n### Examples\r\n\r\n#### response
mode\r\n\r\n```ts\r\nimport { isInferenceRequestAbortedError } from
'@kbn/inference-common';\r\n\r\ntry {\r\n const abortController = new
AbortController();\r\n const chatResponse = await
inferenceClient.chatComplete({\r\n connectorId:
'some-gen-ai-connector',\r\n abortSignal: abortController.signal,\r\n
messages: [{ role: MessageRole.User, content: 'Do something' }],\r\n
});\r\n} catch(e) {\r\n if(isInferenceRequestAbortedError(e)) {\r\n //
request was aborted, do something\r\n } else {\r\n // was another error,
do something else\r\n }\r\n}\r\n\r\n//
elsewhere\r\nabortController.abort()\r\n```\r\n\r\n#### stream
mode\r\n\r\n```ts\r\nimport { isInferenceRequestAbortedError } from
'@kbn/inference-common';\r\n\r\nconst abortController = new
AbortController();\r\nconst events$ = inferenceClient.chatComplete({\r\n
stream: true,\r\n connectorId: 'some-gen-ai-connector',\r\n abortSignal:
abortController.signal,\r\n messages: [{ role: MessageRole.User,
content: 'Do something' }],\r\n});\r\n\r\nevents$.subscribe({\r\n next:
(event) => {\r\n // do something\r\n },\r\n error: (err) => {\r\n
if(isInferenceRequestAbortedError(e)) {\r\n // request was aborted, do
something\r\n } else {\r\n // was another error, do something else\r\n
}\r\n
}\r\n});\r\n\r\nabortController.abort();\r\n```","sha":"0b74f62a338fe1f6b281a019e71279f0d2ffb81f"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/203108","number":203108,"mergeCommit":{"message":"[inference]
Add cancelation support for chatComplete and output (#203108)\n\n##
Summary\r\n\r\nFix
https://github.com/elastic/kibana/issues/200757\r\n\r\nAdd cancelation
support for `chatComplete` and `output`, based on an\r\nabort
signal.\r\n\r\n\r\n### Examples\r\n\r\n#### response
mode\r\n\r\n```ts\r\nimport { isInferenceRequestAbortedError } from
'@kbn/inference-common';\r\n\r\ntry {\r\n const abortController = new
AbortController();\r\n const chatResponse = await
inferenceClient.chatComplete({\r\n connectorId:
'some-gen-ai-connector',\r\n abortSignal: abortController.signal,\r\n
messages: [{ role: MessageRole.User, content: 'Do something' }],\r\n
});\r\n} catch(e) {\r\n if(isInferenceRequestAbortedError(e)) {\r\n //
request was aborted, do something\r\n } else {\r\n // was another error,
do something else\r\n }\r\n}\r\n\r\n//
elsewhere\r\nabortController.abort()\r\n```\r\n\r\n#### stream
mode\r\n\r\n```ts\r\nimport { isInferenceRequestAbortedError } from
'@kbn/inference-common';\r\n\r\nconst abortController = new
AbortController();\r\nconst events$ = inferenceClient.chatComplete({\r\n
stream: true,\r\n connectorId: 'some-gen-ai-connector',\r\n abortSignal:
abortController.signal,\r\n messages: [{ role: MessageRole.User,
content: 'Do something' }],\r\n});\r\n\r\nevents$.subscribe({\r\n next:
(event) => {\r\n // do something\r\n },\r\n error: (err) => {\r\n
if(isInferenceRequestAbortedError(e)) {\r\n // request was aborted, do
something\r\n } else {\r\n // was another error, do something else\r\n
}\r\n
}\r\n});\r\n\r\nabortController.abort();\r\n```","sha":"0b74f62a338fe1f6b281a019e71279f0d2ffb81f"}},{"branch":"8.x","label":"v8.18.0","branchLabelMappingKey":"^v8.18.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Pierre Gayvallet <[email protected]>
JoseLuisGJ pushed a commit to JoseLuisGJ/kibana that referenced this pull request Dec 19, 2024
…tic#203108)

## Summary

Fix elastic#200757

Add cancelation support for `chatComplete` and `output`, based on an
abort signal.


### Examples

#### response mode

```ts
import { isInferenceRequestAbortedError } from '@kbn/inference-common';

try {
  const abortController = new AbortController();
  const chatResponse = await inferenceClient.chatComplete({
    connectorId: 'some-gen-ai-connector',
    abortSignal: abortController.signal,
    messages: [{ role: MessageRole.User, content: 'Do something' }],
  });
} catch(e) {
  if(isInferenceRequestAbortedError(e)) {
    // request was aborted, do something
  } else {
    // was another error, do something else
  }
}

// elsewhere
abortController.abort()
```

#### stream mode

```ts
import { isInferenceRequestAbortedError } from '@kbn/inference-common';

const abortController = new AbortController();
const events$ = inferenceClient.chatComplete({
  stream: true,
  connectorId: 'some-gen-ai-connector',
  abortSignal: abortController.signal,
  messages: [{ role: MessageRole.User, content: 'Do something' }],
});

events$.subscribe({
  next: (event) => {
    // do something
  },
  error: (err) => {
    if(isInferenceRequestAbortedError(e)) {
      // request was aborted, do something
    } else {
      // was another error, do something else
    }
  }
});

abortController.abort();
```
benakansara pushed a commit to benakansara/kibana that referenced this pull request Jan 2, 2025
…tic#203108)

## Summary

Fix elastic#200757

Add cancelation support for `chatComplete` and `output`, based on an
abort signal.


### Examples

#### response mode

```ts
import { isInferenceRequestAbortedError } from '@kbn/inference-common';

try {
  const abortController = new AbortController();
  const chatResponse = await inferenceClient.chatComplete({
    connectorId: 'some-gen-ai-connector',
    abortSignal: abortController.signal,
    messages: [{ role: MessageRole.User, content: 'Do something' }],
  });
} catch(e) {
  if(isInferenceRequestAbortedError(e)) {
    // request was aborted, do something
  } else {
    // was another error, do something else
  }
}

// elsewhere
abortController.abort()
```

#### stream mode

```ts
import { isInferenceRequestAbortedError } from '@kbn/inference-common';

const abortController = new AbortController();
const events$ = inferenceClient.chatComplete({
  stream: true,
  connectorId: 'some-gen-ai-connector',
  abortSignal: abortController.signal,
  messages: [{ role: MessageRole.User, content: 'Do something' }],
});

events$.subscribe({
  next: (event) => {
    // do something
  },
  error: (err) => {
    if(isInferenceRequestAbortedError(e)) {
      // request was aborted, do something
    } else {
      // was another error, do something else
    }
  }
});

abortController.abort();
```
CAWilson94 pushed a commit to CAWilson94/kibana that referenced this pull request Jan 13, 2025
…tic#203108)

## Summary

Fix elastic#200757

Add cancelation support for `chatComplete` and `output`, based on an
abort signal.


### Examples

#### response mode

```ts
import { isInferenceRequestAbortedError } from '@kbn/inference-common';

try {
  const abortController = new AbortController();
  const chatResponse = await inferenceClient.chatComplete({
    connectorId: 'some-gen-ai-connector',
    abortSignal: abortController.signal,
    messages: [{ role: MessageRole.User, content: 'Do something' }],
  });
} catch(e) {
  if(isInferenceRequestAbortedError(e)) {
    // request was aborted, do something
  } else {
    // was another error, do something else
  }
}

// elsewhere
abortController.abort()
```

#### stream mode

```ts
import { isInferenceRequestAbortedError } from '@kbn/inference-common';

const abortController = new AbortController();
const events$ = inferenceClient.chatComplete({
  stream: true,
  connectorId: 'some-gen-ai-connector',
  abortSignal: abortController.signal,
  messages: [{ role: MessageRole.User, content: 'Do something' }],
});

events$.subscribe({
  next: (event) => {
    // do something
  },
  error: (err) => {
    if(isInferenceRequestAbortedError(e)) {
      // request was aborted, do something
    } else {
      // was another error, do something else
    }
  }
});

abortController.abort();
```
viduni94 pushed a commit to viduni94/kibana that referenced this pull request Jan 23, 2025
…tic#203108)

## Summary

Fix elastic#200757

Add cancelation support for `chatComplete` and `output`, based on an
abort signal.


### Examples

#### response mode

```ts
import { isInferenceRequestAbortedError } from '@kbn/inference-common';

try {
  const abortController = new AbortController();
  const chatResponse = await inferenceClient.chatComplete({
    connectorId: 'some-gen-ai-connector',
    abortSignal: abortController.signal,
    messages: [{ role: MessageRole.User, content: 'Do something' }],
  });
} catch(e) {
  if(isInferenceRequestAbortedError(e)) {
    // request was aborted, do something
  } else {
    // was another error, do something else
  }
}

// elsewhere
abortController.abort()
```

#### stream mode

```ts
import { isInferenceRequestAbortedError } from '@kbn/inference-common';

const abortController = new AbortController();
const events$ = inferenceClient.chatComplete({
  stream: true,
  connectorId: 'some-gen-ai-connector',
  abortSignal: abortController.signal,
  messages: [{ role: MessageRole.User, content: 'Do something' }],
});

events$.subscribe({
  next: (event) => {
    // do something
  },
  error: (err) => {
    if(isInferenceRequestAbortedError(e)) {
      // request was aborted, do something
    } else {
      // was another error, do something else
    }
  }
});

abortController.abort();
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:version Backport to applied version labels release_note:skip Skip the PR/issue when compiling release notes Team:AI Infra AppEx AI Infrastructure Team v8.18.0 v9.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[inference] Add support for request cancelation
4 participants