[goose-llm] add providerConfig param for exposed LLM functions (#2491)

This commit is contained in:
Salman Mohammed
2025-05-09 13:09:54 -04:00
committed by GitHub
parent ace269dd06
commit 7b81562351
18 changed files with 3589 additions and 219 deletions
+18 -8
View File
@@ -66,14 +66,23 @@ fun main() = runBlocking {
printMessages(msgs)
println("---\n")
val sessionName = generateSessionName(msgs)
println("Session Name: $sessionName")
// Setup provider
val providerName = "databricks"
val host = System.getenv("DATABRICKS_HOST") ?: error("DATABRICKS_HOST not set")
val token = System.getenv("DATABRICKS_TOKEN") ?: error("DATABRICKS_TOKEN not set")
val providerConfig = """{"host": "$host", "token": "$token"}"""
val tooltip = generateTooltip(msgs)
println("Tooltip: $tooltip")
println("Provider Name: $providerName")
println("Provider Config: $providerConfig")
val sessionName = generateSessionName(providerName, providerConfig, msgs)
println("\nSession Name: $sessionName")
val tooltip = generateTooltip(providerName, providerConfig, msgs)
println("\nTooltip: $tooltip")
// Completion
val provider = "databricks"
val modelName = "goose-gpt-4-1"
val modelConfig = ModelConfig(
modelName,
@@ -116,8 +125,9 @@ fun main() = runBlocking {
val systemPreamble = "You are a helpful assistant."
val req = CompletionRequest(
provider,
val req = createCompletionRequest(
providerName,
providerConfig,
modelConfig,
systemPreamble,
msgs,
@@ -127,4 +137,4 @@ fun main() = runBlocking {
val response = completion(req)
println("\nCompletion Response:")
println(response.message)
}
}
+78 -53
View File
@@ -769,6 +769,8 @@ internal interface IntegrityCheckingUniffiLib : Library {
// Integrity check functions only
fun uniffi_goose_llm_checksum_func_completion(): Short
fun uniffi_goose_llm_checksum_func_create_completion_request(): Short
fun uniffi_goose_llm_checksum_func_create_tool_config(): Short
fun uniffi_goose_llm_checksum_func_generate_session_name(): Short
@@ -821,6 +823,16 @@ internal interface UniffiLib : Library {
// FFI functions
fun uniffi_goose_llm_fn_func_completion(`req`: RustBuffer.ByValue): Long
fun uniffi_goose_llm_fn_func_create_completion_request(
`providerName`: RustBuffer.ByValue,
`providerConfig`: RustBuffer.ByValue,
`modelConfig`: RustBuffer.ByValue,
`systemPreamble`: RustBuffer.ByValue,
`messages`: RustBuffer.ByValue,
`extensions`: RustBuffer.ByValue,
uniffi_out_err: UniffiRustCallStatus,
): RustBuffer.ByValue
fun uniffi_goose_llm_fn_func_create_tool_config(
`name`: RustBuffer.ByValue,
`description`: RustBuffer.ByValue,
@@ -829,9 +841,17 @@ internal interface UniffiLib : Library {
uniffi_out_err: UniffiRustCallStatus,
): RustBuffer.ByValue
fun uniffi_goose_llm_fn_func_generate_session_name(`messages`: RustBuffer.ByValue): Long
fun uniffi_goose_llm_fn_func_generate_session_name(
`providerName`: RustBuffer.ByValue,
`providerConfig`: RustBuffer.ByValue,
`messages`: RustBuffer.ByValue,
): Long
fun uniffi_goose_llm_fn_func_generate_tooltip(`messages`: RustBuffer.ByValue): Long
fun uniffi_goose_llm_fn_func_generate_tooltip(
`providerName`: RustBuffer.ByValue,
`providerConfig`: RustBuffer.ByValue,
`messages`: RustBuffer.ByValue,
): Long
fun uniffi_goose_llm_fn_func_print_messages(
`messages`: RustBuffer.ByValue,
@@ -1067,16 +1087,19 @@ private fun uniffiCheckContractApiVersion(lib: IntegrityCheckingUniffiLib) {
@Suppress("UNUSED_PARAMETER")
private fun uniffiCheckApiChecksums(lib: IntegrityCheckingUniffiLib) {
if (lib.uniffi_goose_llm_checksum_func_completion() != 55281.toShort()) {
if (lib.uniffi_goose_llm_checksum_func_completion() != 47457.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_goose_llm_checksum_func_create_completion_request() != 51008.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_goose_llm_checksum_func_create_tool_config() != 22809.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_goose_llm_checksum_func_generate_session_name() != 61290.toShort()) {
if (lib.uniffi_goose_llm_checksum_func_generate_session_name() != 9810.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_goose_llm_checksum_func_generate_tooltip() != 7529.toShort()) {
if (lib.uniffi_goose_llm_checksum_func_generate_tooltip() != 15466.toShort()) {
throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
if (lib.uniffi_goose_llm_checksum_func_print_messages() != 30278.toShort()) {
@@ -1365,50 +1388,6 @@ public object FfiConverterString : FfiConverter<String, RustBuffer.ByValue> {
}
}
data class CompletionRequest(
var `providerName`: kotlin.String,
var `modelConfig`: ModelConfig,
var `systemPreamble`: kotlin.String,
var `messages`: List<Message>,
var `extensions`: List<ExtensionConfig>,
) {
companion object
}
/**
* @suppress
*/
public object FfiConverterTypeCompletionRequest : FfiConverterRustBuffer<CompletionRequest> {
override fun read(buf: ByteBuffer): CompletionRequest =
CompletionRequest(
FfiConverterString.read(buf),
FfiConverterTypeModelConfig.read(buf),
FfiConverterString.read(buf),
FfiConverterSequenceTypeMessage.read(buf),
FfiConverterSequenceTypeExtensionConfig.read(buf),
)
override fun allocationSize(value: CompletionRequest) =
(
FfiConverterString.allocationSize(value.`providerName`) +
FfiConverterTypeModelConfig.allocationSize(value.`modelConfig`) +
FfiConverterString.allocationSize(value.`systemPreamble`) +
FfiConverterSequenceTypeMessage.allocationSize(value.`messages`) +
FfiConverterSequenceTypeExtensionConfig.allocationSize(value.`extensions`)
)
override fun write(
value: CompletionRequest,
buf: ByteBuffer,
) {
FfiConverterString.write(value.`providerName`, buf)
FfiConverterTypeModelConfig.write(value.`modelConfig`, buf)
FfiConverterString.write(value.`systemPreamble`, buf)
FfiConverterSequenceTypeMessage.write(value.`messages`, buf)
FfiConverterSequenceTypeExtensionConfig.write(value.`extensions`, buf)
}
}
data class CompletionResponse(
var `message`: Message,
var `model`: kotlin.String,
@@ -2814,6 +2793,14 @@ public object FfiConverterSequenceTypeToolConfig : FfiConverterRustBuffer<List<T
}
}
/**
* Typealias from the type name used in the UDL file to the builtin type. This
* is needed because the UDL type name is used in function/method signatures.
* It's also what we have an external type that references a custom type.
*/
public typealias CompletionRequest = kotlin.String
public typealias FfiConverterTypeCompletionRequest = FfiConverterString
/**
* Typealias from the type name used in the UDL file to the builtin type. This
* is needed because the UDL type name is used in function/method signatures.
@@ -2871,6 +2858,28 @@ suspend fun `completion`(`req`: CompletionRequest): CompletionResponse =
CompletionException.ErrorHandler,
)
fun `createCompletionRequest`(
`providerName`: kotlin.String,
`providerConfig`: JsonValueFfi,
`modelConfig`: ModelConfig,
`systemPreamble`: kotlin.String,
`messages`: List<Message>,
`extensions`: List<ExtensionConfig>,
): CompletionRequest =
FfiConverterTypeCompletionRequest.lift(
uniffiRustCall { _status ->
UniffiLib.INSTANCE.uniffi_goose_llm_fn_func_create_completion_request(
FfiConverterString.lower(`providerName`),
FfiConverterTypeJsonValueFfi.lower(`providerConfig`),
FfiConverterTypeModelConfig.lower(`modelConfig`),
FfiConverterString.lower(`systemPreamble`),
FfiConverterSequenceTypeMessage.lower(`messages`),
FfiConverterSequenceTypeExtensionConfig.lower(`extensions`),
_status,
)
},
)
fun `createToolConfig`(
`name`: kotlin.String,
`description`: kotlin.String,
@@ -2894,9 +2903,17 @@ fun `createToolConfig`(
*/
@Throws(ProviderException::class)
@Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE")
suspend fun `generateSessionName`(`messages`: List<Message>): kotlin.String =
suspend fun `generateSessionName`(
`providerName`: kotlin.String,
`providerConfig`: JsonValueFfi,
`messages`: List<Message>,
): kotlin.String =
uniffiRustCallAsync(
UniffiLib.INSTANCE.uniffi_goose_llm_fn_func_generate_session_name(FfiConverterSequenceTypeMessage.lower(`messages`)),
UniffiLib.INSTANCE.uniffi_goose_llm_fn_func_generate_session_name(
FfiConverterString.lower(`providerName`),
FfiConverterTypeJsonValueFfi.lower(`providerConfig`),
FfiConverterSequenceTypeMessage.lower(`messages`),
),
{ future, callback, continuation -> UniffiLib.INSTANCE.ffi_goose_llm_rust_future_poll_rust_buffer(future, callback, continuation) },
{ future, continuation -> UniffiLib.INSTANCE.ffi_goose_llm_rust_future_complete_rust_buffer(future, continuation) },
{ future -> UniffiLib.INSTANCE.ffi_goose_llm_rust_future_free_rust_buffer(future) },
@@ -2912,9 +2929,17 @@ suspend fun `generateSessionName`(`messages`: List<Message>): kotlin.String =
*/
@Throws(ProviderException::class)
@Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE")
suspend fun `generateTooltip`(`messages`: List<Message>): kotlin.String =
suspend fun `generateTooltip`(
`providerName`: kotlin.String,
`providerConfig`: JsonValueFfi,
`messages`: List<Message>,
): kotlin.String =
uniffiRustCallAsync(
UniffiLib.INSTANCE.uniffi_goose_llm_fn_func_generate_tooltip(FfiConverterSequenceTypeMessage.lower(`messages`)),
UniffiLib.INSTANCE.uniffi_goose_llm_fn_func_generate_tooltip(
FfiConverterString.lower(`providerName`),
FfiConverterTypeJsonValueFfi.lower(`providerConfig`),
FfiConverterSequenceTypeMessage.lower(`messages`),
),
{ future, callback, continuation -> UniffiLib.INSTANCE.ffi_goose_llm_rust_future_poll_rust_buffer(future, callback, continuation) },
{ future, continuation -> UniffiLib.INSTANCE.ffi_goose_llm_rust_future_complete_rust_buffer(future, continuation) },
{ future -> UniffiLib.INSTANCE.ffi_goose_llm_rust_future_free_rust_buffer(future) },
File diff suppressed because it is too large Load Diff
+133
View File
@@ -0,0 +1,133 @@
import asyncio
import os
import time
from goose_llm import (
Message, MessageContent, TextContent, ToolRequest, ToolResponse,
Role, ModelConfig, ToolApprovalMode,
create_tool_config, ExtensionConfig,
generate_session_name, generate_tooltip,
create_completion_request, completion
)
async def main():
now = int(time.time())
# 1) User sends a plain-text prompt
messages = [
Message(
role=Role.USER,
created=now,
content=[MessageContent.TEXT(TextContent(text="What is 7 x 6?"))]
),
# 2) Assistant makes a tool request
Message(
role=Role.ASSISTANT,
created=now + 2,
content=[MessageContent.TOOL_REQ(ToolRequest(
id="calc1",
tool_call="""
{
"status": "success",
"value": {
"name": "calculator_extension__toolname",
"arguments": {
"operation": "multiply",
"numbers": [7, 6]
},
"needsApproval": false
}
}
"""
))]
),
# 3) User sends tool result
Message(
role=Role.USER,
created=now + 3,
content=[MessageContent.TOOL_RESP(ToolResponse(
id="calc1",
tool_result="""
{
"status": "success",
"value": [
{"type": "text", "text": "42"}
]
}
"""
))]
)
]
provider_name = "databricks"
provider_config = f'''{{
"host": "{os.environ.get("DATABRICKS_HOST")}",
"token": "{os.environ.get("DATABRICKS_TOKEN")}"
}}'''
print(f"Provider Name: {provider_name}")
print(f"Provider Config: {provider_config}")
session_name = await generate_session_name(provider_name, provider_config, messages)
print(f"\nSession Name: {session_name}")
tooltip = await generate_tooltip(provider_name, provider_config, messages)
print(f"\nTooltip: {tooltip}")
model_config = ModelConfig(
model_name="goose-gpt-4-1",
max_tokens=500,
temperature=0.1,
context_limit=4096,
)
calculator_tool = create_tool_config(
name="calculator",
description="Perform basic arithmetic operations",
input_schema="""
{
"type": "object",
"required": ["operation", "numbers"],
"properties": {
"operation": {
"type": "string",
"enum": ["add", "subtract", "multiply", "divide"],
"description": "The arithmetic operation to perform"
},
"numbers": {
"type": "array",
"items": { "type": "number" },
"description": "List of numbers to operate on in order"
}
}
}
""",
approval_mode=ToolApprovalMode.AUTO
)
calculator_extension = ExtensionConfig(
name="calculator_extension",
instructions="This extension provides a calculator tool.",
tools=[calculator_tool]
)
system_preamble = "You are a helpful assistant."
extensions = [calculator_extension]
req = create_completion_request(
provider_name,
provider_config,
model_config,
system_preamble,
messages,
extensions
)
resp = await completion(req)
print(f"\nCompletion Response:\n{resp.message}")
print(f"Msg content: {resp.message.content[0][0]}")
if __name__ == "__main__":
asyncio.run(main())