Closed bcherry closed 6 months ago
This should take care of what you need, now you can retrieve the content you want, see the Demo example on how I can get the string value of the JSON https://github.com/jamesrochabrun/SwiftAnthropic/pull/9 Let me know how that goes!
Ooh looks good, that should be perfect. I will try this out soon!
@jamesrochabrun for our use case we are hoping to get rich typed outputs rather than a more free-form dictionary. Luckily what you did works if you also make DynamicContent encodable. This seems to work just fine. I tested it with arrays of dictionaries and everything.
public func encode(to encoder: any Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .string(let val):
try container.encode(val)
case .integer(let val):
try container.encode(val)
case .double(let val):
try container.encode(val)
case .dictionary(let val):
try container.encode(val)
case .array(let val):
try container.encode(val)
case .bool(let val):
try container.encode(val)
case .null:
try container.encodeNil()
}
}
Then we can easily get what we need in our code by turning it back to JSON with JSONEncoder().encode(input)
then can reparse with our type.
@bcherry do you want to open a PR with your example? Also make sure to test your changes against the demo app, both for messages and function calling. I will take a look later today. thanks.
I'm going to leave it alone today - it's now integrated into our app like that and working but i still need to use my fork anyways to use a basePath that has a partial path component so I'll wait til we sort that out and revisit!
Love the quick update to support new tools / functions!
I ran into an issue integrating it when using complex function types. I have functions that have arrays and nested object types. All are supported by JSONSchema, and thus by Claude 3 in the new beta release.
However, the
Content
type in this library hardcodes function responses as[String: String]
- that is, a single layer dictionary of string values. If your function call has a more complex return type, it won't parse.The solution I've found required a deep change - instead of decoding the
input
key to[String: String]
, I just pass the rawcontainer
up to the caller and let it parse theinput
key with its own type definition. This works but it's super messy.You can see what I mean over here in this fork, but it's not suitable for submitting a PR: https://github.com/bcherry/SwiftAnthropic/commit/624aec8916cc4b039a7efca1efae9e4941c16c2a
I'm not an expert on Swift encoding/decoding nor generics so maybe there's a cleaner way to accomplish this?