tool format hardening
This commit is contained in:
@@ -94,10 +94,27 @@ sub shell_exec {
|
||||
return trim($res) . "\n\nexit: $code";
|
||||
}
|
||||
|
||||
sub sanitize_msgs {
|
||||
my ($msgs) = @_;
|
||||
return unless $msgs && ref($msgs) eq 'ARRAY';
|
||||
for my $m (@$msgs) {
|
||||
next unless ref($m) eq 'HASH' && ($m->{role} // '') eq 'assistant' && $m->{tool_calls};
|
||||
for my $tc (@{$m->{tool_calls}}) {
|
||||
next unless ref($tc) eq 'HASH' && $tc->{function};
|
||||
my $astr = $tc->{function}{arguments} // '{}';
|
||||
my $a = eval { decode_json($astr) };
|
||||
if ($@ || ref($a) ne 'HASH') {
|
||||
$tc->{function}{arguments} = encode_json({ invalid_raw => $astr // '' });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my @fib = (1, 1, 2, 3, 5, 8, 13, 21, 34);
|
||||
|
||||
sub llm {
|
||||
my ($cfg, $msgs, $tools) = @_;
|
||||
sanitize_msgs($msgs);
|
||||
my $ep = $cfg->{endpoint} =~ s/\/+$//r;
|
||||
my $url = "$ep/chat/completions";
|
||||
my %h = ('Content-Type' => 'application/json', 'User-Agent' => 'Mozilla/5.0 (compatible; Bantam/1.0)');
|
||||
@@ -119,8 +136,10 @@ sub llm {
|
||||
my $d = eval { decode_json($res->{content}) };
|
||||
return $d->{choices}[0]{message} if $d && $d->{choices} && @{$d->{choices}};
|
||||
}
|
||||
my $err = $res->{reason} || $res->{content} || "HTTP status $res->{status}";
|
||||
my $status = $res->{status} // 0;
|
||||
my $err = $res->{reason} || $res->{content} || "HTTP status $status";
|
||||
print "\r\e[K" if $_col; STDOUT->flush();
|
||||
die "[HTTP error: $err]\n" if $status >= 400 && $status < 500 && $status != 408 && $status != 429;
|
||||
if ($i <= $#fib) { print c("[network error: $err, retrying in ${dly}s...]", 31), "\n"; sleep($dly); next; }
|
||||
die "[network error: $err]\n";
|
||||
} else {
|
||||
@@ -175,8 +194,10 @@ sub llm {
|
||||
$msg{tool_calls} = [map { $tcs{$_} } @order] if @order;
|
||||
return \%msg;
|
||||
}
|
||||
my $err = $res->{reason} || $res->{content} || "HTTP status $res->{status}";
|
||||
my $status = $res->{status} // 0;
|
||||
my $err = $res->{reason} || $res->{content} || "HTTP status $status";
|
||||
print "\r\e[K" if $_col; STDOUT->flush();
|
||||
die "[HTTP error: $err]\n" if $status >= 400 && $status < 500 && $status != 408 && $status != 429;
|
||||
if ($i <= $#fib) { print c("[network error: $err, retrying in ${dly}s...]", 31), "\n"; sleep($dly); next; }
|
||||
die "[network error: $err]\n";
|
||||
}
|
||||
@@ -208,6 +229,7 @@ sub AL {
|
||||
my ($res, $sty) = ('', 2);
|
||||
my $a = eval { decode_json($astr) };
|
||||
if ($@ || ref($a) ne 'HASH') {
|
||||
$tc->{function}{arguments} = encode_json({ invalid_raw => $astr });
|
||||
$res = "[tool error: invalid JSON args for $fn: " . ($@ || 'not a JSON object') . ". Raw: '$astr']"; $sty = 31;
|
||||
} elsif ($fn eq 'shell_exec') {
|
||||
$res = shell_exec($a->{command} // '', $stime);
|
||||
|
||||
Reference in New Issue
Block a user