chore: generate
This commit is contained in:
+40
-31
@@ -242,7 +242,8 @@ executable tools. Call-level values override model defaults.
|
|||||||
Provider-specific options are inferred from the concrete model:
|
Provider-specific options are inferred from the concrete model:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
yield* LLM.generate({
|
yield *
|
||||||
|
LLM.generate({
|
||||||
model: OpenAI.model("gpt-4.1-mini"),
|
model: OpenAI.model("gpt-4.1-mini"),
|
||||||
prompt: "Hello",
|
prompt: "Hello",
|
||||||
provider: {
|
provider: {
|
||||||
@@ -278,7 +279,9 @@ provider.
|
|||||||
### Inline input
|
### Inline input
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const result = yield* LLM.generate({
|
const result =
|
||||||
|
yield *
|
||||||
|
LLM.generate({
|
||||||
model,
|
model,
|
||||||
system: "You are concise.",
|
system: "You are concise.",
|
||||||
prompt: "Summarize this pull request.",
|
prompt: "Summarize this pull request.",
|
||||||
@@ -362,7 +365,9 @@ const tools = {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = yield* LLM.generate({
|
const result =
|
||||||
|
yield *
|
||||||
|
LLM.generate({
|
||||||
model,
|
model,
|
||||||
prompt: "What is the weather in London?",
|
prompt: "What is the weather in London?",
|
||||||
tools,
|
tools,
|
||||||
@@ -387,14 +392,13 @@ successful result with `stopReason: "max-turns"`, not an Effect failure.
|
|||||||
### Custom stopping
|
### Custom stopping
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const result = yield* LLM.generate({
|
const result =
|
||||||
|
yield *
|
||||||
|
LLM.generate({
|
||||||
model,
|
model,
|
||||||
prompt,
|
prompt,
|
||||||
tools,
|
tools,
|
||||||
stopWhen: StopWhen.any(
|
stopWhen: StopWhen.any(StopWhen.turnCount(8), StopWhen.hasToolCall("finalize")),
|
||||||
StopWhen.turnCount(8),
|
|
||||||
StopWhen.hasToolCall("finalize"),
|
|
||||||
),
|
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -433,11 +437,7 @@ const call = Array.from(events).find(LLMEvent.is.toolCall)
|
|||||||
if (call && !call.providerExecuted) {
|
if (call && !call.providerExecuted) {
|
||||||
const dispatched = yield * ToolRuntime.dispatch(tools, call)
|
const dispatched = yield * ToolRuntime.dispatch(tools, call)
|
||||||
const followUp = LLM.updateRequest(request, {
|
const followUp = LLM.updateRequest(request, {
|
||||||
messages: [
|
messages: [...request.messages, Message.assistant([call]), Message.tool({ ...call, result: dispatched.result })],
|
||||||
...request.messages,
|
|
||||||
Message.assistant([call]),
|
|
||||||
Message.tool({ ...call, result: dispatched.result }),
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
// Caller must invoke the provider again and repeat the loop.
|
// Caller must invoke the provider again and repeat the loop.
|
||||||
}
|
}
|
||||||
@@ -452,7 +452,9 @@ OpenCode and other durable runtimes need to own persistence, tool settlement,
|
|||||||
and continuation. They use the explicit turn API:
|
and continuation. They use the explicit turn API:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const result = yield* LLM.generateTurn({
|
const result =
|
||||||
|
yield *
|
||||||
|
LLM.generateTurn({
|
||||||
model,
|
model,
|
||||||
request,
|
request,
|
||||||
// Definitions only. generateTurn never dispatches local handlers.
|
// Definitions only. generateTurn never dispatches local handlers.
|
||||||
@@ -494,7 +496,9 @@ const request = LLM.request({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const result = yield* LLM.generate({
|
const result =
|
||||||
|
yield *
|
||||||
|
LLM.generate({
|
||||||
model,
|
model,
|
||||||
request,
|
request,
|
||||||
tools: {
|
tools: {
|
||||||
@@ -516,7 +520,9 @@ binding. Missing or incompatible bindings fail with a typed tool-binding error.
|
|||||||
Provider-hosted tools are distinct typed values:
|
Provider-hosted tools are distinct typed values:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const result = yield* LLM.generate({
|
const result =
|
||||||
|
yield *
|
||||||
|
LLM.generate({
|
||||||
model: OpenAI.model("gpt-4.1"),
|
model: OpenAI.model("gpt-4.1"),
|
||||||
prompt: "Find today's relevant announcements.",
|
prompt: "Find today's relevant announcements.",
|
||||||
tools: {
|
tools: {
|
||||||
@@ -589,7 +595,9 @@ const Weather = Schema.Struct({
|
|||||||
highCelsius: Schema.Number,
|
highCelsius: Schema.Number,
|
||||||
})
|
})
|
||||||
|
|
||||||
const result = yield* LLM.generate({
|
const result =
|
||||||
|
yield *
|
||||||
|
LLM.generate({
|
||||||
model,
|
model,
|
||||||
prompt: "Give me today's weather for London.",
|
prompt: "Give me today's weather for London.",
|
||||||
output: Weather,
|
output: Weather,
|
||||||
@@ -612,7 +620,9 @@ Advanced callers may override the strategy when exact provider semantics matter.
|
|||||||
|
|
||||||
```ts
|
```ts
|
||||||
// Current API is a separate operation and always forces a synthetic tool.
|
// Current API is a separate operation and always forces a synthetic tool.
|
||||||
const result = yield* LLM.generateObject({
|
const result =
|
||||||
|
yield *
|
||||||
|
LLM.generateObject({
|
||||||
model,
|
model,
|
||||||
prompt,
|
prompt,
|
||||||
schema: Weather,
|
schema: Weather,
|
||||||
@@ -679,7 +689,8 @@ cache boundaries where explicit caching is supported and does nothing on the wir
|
|||||||
where providers cache implicitly.
|
where providers cache implicitly.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
yield* LLM.generate({
|
yield *
|
||||||
|
LLM.generate({
|
||||||
model,
|
model,
|
||||||
prompt,
|
prompt,
|
||||||
cache: "none", // Explicit opt-out.
|
cache: "none", // Explicit opt-out.
|
||||||
@@ -705,7 +716,8 @@ silently inherit custom retry policies.
|
|||||||
### Timeouts
|
### Timeouts
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
yield* LLM.generate({
|
yield *
|
||||||
|
LLM.generate({
|
||||||
model,
|
model,
|
||||||
prompt,
|
prompt,
|
||||||
timeout: "2 minutes", // Entire run, including tools.
|
timeout: "2 minutes", // Entire run, including tools.
|
||||||
@@ -740,7 +752,8 @@ retry, or redirect control flow.
|
|||||||
```ts
|
```ts
|
||||||
const model = OpenAI.model("gpt-4.1", {
|
const model = OpenAI.model("gpt-4.1", {
|
||||||
hooks: {
|
hooks: {
|
||||||
request: (request) => Effect.succeed({
|
request: (request) =>
|
||||||
|
Effect.succeed({
|
||||||
...request,
|
...request,
|
||||||
metadata: { ...request.metadata, tenant: "acme" },
|
metadata: { ...request.metadata, tenant: "acme" },
|
||||||
}),
|
}),
|
||||||
@@ -775,7 +788,8 @@ The request customization ladder is:
|
|||||||
5. Experimental provider-definition or protocol patching
|
5. Experimental provider-definition or protocol patching
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
yield* LLM.generate({
|
yield *
|
||||||
|
LLM.generate({
|
||||||
model,
|
model,
|
||||||
prompt,
|
prompt,
|
||||||
http: {
|
http: {
|
||||||
@@ -928,10 +942,7 @@ Provider authoring is public but experimental.
|
|||||||
### Declarative provider definition
|
### Declarative provider definition
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import {
|
import { Provider, Protocol } from "@opencode-ai/ai/provider"
|
||||||
Provider,
|
|
||||||
Protocol,
|
|
||||||
} from "@opencode-ai/ai/provider"
|
|
||||||
|
|
||||||
export const ExampleAI = Provider.define({
|
export const ExampleAI = Provider.define({
|
||||||
id: "example",
|
id: "example",
|
||||||
@@ -996,9 +1007,7 @@ SDK integrations that motivated this package.
|
|||||||
const PatchedResponses = OpenAIResponses.with({
|
const PatchedResponses = OpenAIResponses.with({
|
||||||
body: {
|
body: {
|
||||||
fromRequest: (request) =>
|
fromRequest: (request) =>
|
||||||
OpenAIResponses.body.fromRequest(request).pipe(
|
OpenAIResponses.body.fromRequest(request).pipe(Effect.map((body) => ({ ...body, custom_field: true }))),
|
||||||
Effect.map((body) => ({ ...body, custom_field: true })),
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
stream: {
|
stream: {
|
||||||
step: patchResponsesStep,
|
step: patchResponsesStep,
|
||||||
@@ -1043,7 +1052,7 @@ providers, and there is no preferred all-providers barrel.
|
|||||||
## Defaults
|
## Defaults
|
||||||
|
|
||||||
| Concern | Default |
|
| Concern | Default |
|
||||||
| --- | --- |
|
| ---------------------------- | --------------------------------------------------- |
|
||||||
| `LLM.generate` semantics | Complete Model Run |
|
| `LLM.generate` semantics | Complete Model Run |
|
||||||
| `LLM.generateTurn` semantics | Exactly one Provider Turn |
|
| `LLM.generateTurn` semantics | Exactly one Provider Turn |
|
||||||
| Maximum turns | 20 |
|
| Maximum turns | 20 |
|
||||||
@@ -1064,7 +1073,7 @@ providers, and there is no preferred all-providers barrel.
|
|||||||
The redesign intentionally removes or changes these current concepts:
|
The redesign intentionally removes or changes these current concepts:
|
||||||
|
|
||||||
| Current | Proposed |
|
| Current | Proposed |
|
||||||
| --- | --- |
|
| --------------------------------------- | ----------------------------------------------------------- |
|
||||||
| `@opencode-ai/llm` | `@opencode-ai/ai` |
|
| `@opencode-ai/llm` | `@opencode-ai/ai` |
|
||||||
| Mandatory `LLM.request({ model, ... })` | Inline calls or model-free portable requests |
|
| Mandatory `LLM.request({ model, ... })` | Inline calls or model-free portable requests |
|
||||||
| `LLM.generate` means one turn | `LLM.generate` means complete run |
|
| `LLM.generate` means one turn | `LLM.generate` means complete run |
|
||||||
|
|||||||
Reference in New Issue
Block a user