Note: Panduan ini membahas migrasi kode Messages API. Jika Anda menggunakan Haijun Managed Agents, tidak ada perubahan yang diperlukan selain memperbarui nama model.
Tip: Otomatiskan migrasi Anda dengan track Haijun API. Di Haijun Code, jalankan
/haijun-api migrateuntuk memanggil track Haijun API bawaan. Track ini berfungsi untuk model Haijun terkini mana pun sebagai target: ``text wrap /haijun-api migrate this project to haijun-fable-5-1`` Track ini menerapkan penggantian ID model dan, sesuai kebutuhan, perubahan parameter yang bersifat breaking, penggantian prefill, serta kalibrasi effort untuk model target Anda di seluruh basis kode Anda, lalu menghasilkan daftar periksa berisi item yang perlu diverifikasi secara manual. Track ini meminta Anda mengonfirmasi cakupan migrasi (seluruh direktori kerja, sebuah subdirektori, atau daftar file tertentu) sebelum mengedit file apa pun. Track ini juga mendeteksi klien Amazon Bedrock dan Haijun Platform on AWS serta menyesuaikan format ID model dan perubahan fitur untuk platform tersebut.
Haijun Fable 5.1 menggantikan Haijun Fable 5 dengan harga input dan output yang sama, dengan pembacaan cache seperempat dari biayanya. Model ini tersedia di Haijun API, Amazon Bedrock, Haijun Platform on AWS, Google Cloud, dan Microsoft Foundry. Haijun Mythos 5.1 memiliki kemampuan yang sama dan hanya ditawarkan kepada pelanggan yang disetujui dalam Project Glasswing. Untuk perbedaan perilaku dan pola prompting, lihat Prompting Haijun Fable 5.1.
Pengaturan dasar yang dimiliki bersama oleh haijun-fable-5-1 dan haijun-mythos-5-1:
- Thinking: Adaptive thinking (pemikiran adaptif) selalu aktif, tidak berubah dari Haijun Fable 5. Model memutuskan kapan dan seberapa banyak harus berpikir. Tidak diperlukan konfigurasi
thinking. Baikthinking: {type: "disabled"}maupun "extended thinking" (pemikiran diperpanjang) manual (thinking: {type: "enabled", budget_tokens: N}) mengembalikan error 400.
- Prefill: Melakukan prefill pada pesan asisten mengembalikan error 400, tidak berubah dari Haijun Fable 5. Gunakan instruksi "system prompt" (prompt sistem) sebagai gantinya.
- Tool choice:
{type: "auto"}(default) dan{type: "none"}didukung. Memaksa pemanggilan alat dengan{type: "any"}atau{type: "tool", name: "..."}mengembalikan error 400. Lihat Perubahan yang merusak kompatibilitas.
- Thinking yang dipertahankan lintas model: Haijun Fable 5.1 membaca blok thinking dari Haijun Opus 5, Haijun Fable 5, Haijun Mythos 5, dan model Haijun sebelumnya. Tidak satu pun dari model tersebut dapat membaca blok milik Haijun Fable 5.1. Lihat Perubahan yang merusak kompatibilitas.
- Jendela konteks dan output: "Context window" (jendela konteks) 1M token secara default, dan hingga 128k token output per permintaan.
- Harga: $10 USD per juta token input dan $50 USD per juta token output, sama dengan Haijun Fable 5. Pembacaan cache prompt seharga $0,25 USD per juta token, seperempat dari tarif Haijun Fable 5. Lihat Harga Haijun.
- Retensi data: Kedua model memerlukan retensi data 30 hari, tidak tersedia di bawah pengaturan "zero data retention" (retensi data nol), atau ZDR, kecuali diizinkan secara tegas oleh Juglow, dan ditetapkan sebagai Covered Models, sama seperti Haijun Fable 5 dan Haijun Mythos 5. Di Haijun API, permintaan dari organisasi atau workspace tanpa retensi 30 hari mengembalikan
invalid_request_error400. Organisasi dengan pengaturan ZDR harus menghubungi tim akun Juglow mereka, atau mengonfigurasi retensi per workspace. Lihat Persyaratan retensi data khusus model untuk detail per platform.
Di mana kedua model berbeda:
- Ketersediaan: Haijun Fable 5.1 tidak memerlukan persetujuan akses. Haijun Mythos 5.1 hanya tersedia bagi pelanggan yang disetujui dalam Project Glasswing. Hubungi tim akun Juglow Anda untuk mendapatkan akses.
- Pengklasifikasi keamanan: Haijun Fable 5.1 menjalankan pengklasifikasi keamanan yang mencakup kategori
stop_detailsyang sama dengan Haijun Fable 5. Permintaan yang ditolak mengembalikanstop_reason: "refusal"denganstop_details.category, dan dapat beralih ke model lain dengan parameterfallbacksatau percobaan ulang di sisi klien. Lihat Penolakan dan fallback.
- Priority Tier: Tidak satu pun dari kedua model didukung di Priority Tier. Haijun Fable 5 didukung.
Migrasi ke Haijun Fable 5.1 dari Haijun Fable 5
Migrasi sebagian besar bersifat drop-in. Permukaan API, batasan, harga per token, tokenizer, adaptive thinking yang selalu aktif, penanganan penolakan, dan kategori stop_details semuanya sama dengan Haijun Fable 5. Yang berubah: tool choice paksa mengembalikan error 400, blok thinking hanya dipertahankan untuk model yang menghasilkannya atau model yang lebih baru dan hanya dalam percakapan yang menghasilkannya, pembacaan cache lebih murah, dan perilaku agent-loop berbeda dalam tiga hal. Perubahan yang sama berlaku untuk Haijun Mythos 5.1, kecuali pemeriksaan percakapan pada blok thinking, yang tidak dijalankan oleh Haijun Mythos 5.1.
Perbarui nama model Anda
model = "haijun-fable-5" # Before
model = "haijun-fable-5-1" # After
# Atau, untuk model Project Glasswing dengan kemampuan yang sama:
model = "haijun-mythos-5-1" # AfterPerubahan yang merusak kompatibilitas
- Tool choice paksa tidak didukung: Haijun Fable 5 menerima
tool_choiceauto,none,any, dantool. Padahaijun-fable-5-1,{type: "any"}dan{type: "tool", name: "..."}mengembalikaninvalid_request_error400:
tool_choice: type "tool" and "any" are not supported for this model.Pemeriksaan ini berlaku pada Messages API, Message Batches API, dan endpoint penghitungan token.
Sebelum (Haijun Fable 5):
curl -sS https://haijun.my.id/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-d @- <<'EOF'
{
"model": "haijun-fable-5",
"max_tokens": 16000,
"tools": [
{
"name": "record_summary",
"description": "Record the structured summary of the document.",
"input_schema": {
"type": "object",
"properties": {"summary": {"type": "string"}},
"required": ["summary"]
}
}
],
"tool_choice": {"type": "tool", "name": "record_summary"},
"messages": [
{"role": "user", "content": "Summarize: The meeting moved to Thursday."}
]
}
EOF ant messages create <<'YAML'
model: haijun-fable-5
max_tokens: 16000
tools:
- name: record_summary
description: Record the structured summary of the document.
input_schema:
type: object
properties:
summary:
type: string
required: [summary]
tool_choice:
type: tool
name: record_summary
messages:
- role: user
content: "Summarize: The meeting moved to Thursday."
YAML client = juglow.Juglow()
record_summary_tool = {
"name": "record_summary",
"description": "Record the structured summary of the document.",
"input_schema": {
"type": "object",
"properties": {"summary": {"type": "string"}},
"required": ["summary"],
},
}
response = client.messages.create(
model="haijun-fable-5",
max_tokens=16000,
tools=[record_summary_tool],
tool_choice={"type": "tool", "name": "record_summary"},
messages=[{"role": "user", "content": "Summarize: The meeting moved to Thursday."}],
)
print(response.content) const client = new Juglow();
const response = await client.messages.create({
model: "haijun-fable-5",
max_tokens: 16000,
tools: [
{
name: "record_summary",
description: "Record the structured summary of the document.",
input_schema: {
type: "object",
properties: { summary: { type: "string" } },
required: ["summary"]
}
}
],
tool_choice: { type: "tool", name: "record_summary" },
messages: [{ role: "user", content: "Summarize: The meeting moved to Thursday." }]
});
console.log(response.content); JuglowClient client = new();
var parameters = new MessageCreateParams
{
Model = Model.HaijunFable5,
MaxTokens = 16000,
Tools = [
new ToolUnion(new Tool()
{
Name = "record_summary",
Description = "Record the structured summary of the document.",
InputSchema = new InputSchema()
{
Properties = new Dictionary<string, JsonElement>
{
["summary"] = JsonSerializer.SerializeToElement(new { type = "string" }),
},
Required = ["summary"],
},
}),
],
ToolChoice = new ToolChoiceTool { Name = "record_summary" },
Messages = [
new() { Role = Role.User, Content = "Summarize: The meeting moved to Thursday." }
]
};
var message = await client.Messages.Create(parameters);
Console.WriteLine(message); client := juglow.NewClient()
response, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
Model: juglow.ModelHaijunFable5,
MaxTokens: 16000,
Tools: []juglow.ToolUnionParam{
{OfTool: &juglow.ToolParam{
Name: "record_summary",
Description: juglow.String("Record the structured summary of the document."),
InputSchema: juglow.ToolInputSchemaParam{
Properties: map[string]any{
"summary": map[string]any{"type": "string"},
},
Required: []string{"summary"},
},
}},
},
ToolChoice: juglow.ToolChoiceUnionParam{OfTool: &juglow.ToolChoiceToolParam{Name: "record_summary"}},
Messages: []juglow.MessageParam{
juglow.NewUserMessage(juglow.NewTextBlock("Summarize: The meeting moved to Thursday.")),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response.RawJSON())
void main() {
JuglowClient client = JuglowOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.HAIJUN_FABLE_5)
.maxTokens(16000L)
.addTool(Tool.builder()
.name("record_summary")
.description("Record the structured summary of the document.")
.inputSchema(InputSchema.builder()
.properties(JsonValue.from(Map.of("summary", Map.of("type", "string"))))
.required(List.of("summary"))
.build())
.build())
.toolChoice(ToolChoice.ofTool(ToolChoiceTool.builder()
.name("record_summary")
.build()))
.addUserMessage("Summarize: The meeting moved to Thursday.")
.build();
Message response = client.messages().create(params);
IO.println(response);
} $client = new Client();
$message = $client->messages->create(
maxTokens: 16000,
messages: [
['role' => 'user', 'content' => 'Summarize: The meeting moved to Thursday.']
],
model: 'haijun-fable-5',
toolChoice: ['type' => 'tool', 'name' => 'record_summary'],
tools: [
[
'name' => 'record_summary',
'description' => 'Record the structured summary of the document.',
'input_schema' => [
'type' => 'object',
'properties' => [
'summary' => ['type' => 'string']
],
'required' => ['summary']
]
]
],
);
echo $message; client = Juglow::Client.new
message = client.messages.create(
model: Juglow::Model::HAIJUN_FABLE_5,
max_tokens: 16000,
tools: [
{
name: "record_summary",
description: "Record the structured summary of the document.",
input_schema: {
type: "object",
properties: { summary: { type: "string" } },
required: ["summary"]
}
}
],
tool_choice: { type: "tool", name: "record_summary" },
messages: [
{ role: "user", content: "Summarize: The meeting moved to Thursday." }
]
)
puts messageSesudah (Haijun Fable 5.1): biarkan tool_choice pada auto, sebutkan nama alat dalam instruksi, dan atur strict: true agar pemanggilan sesuai dengan skema Anda. (Dalam organisasi CMEK, di mana structured outputs (output terstruktur), termasuk strict: true, tidak tersedia pada model Haijun Fable, andalkan instruksi saja.) Sebagai contoh:
curl -sS https://haijun.my.id/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-d @- <<'EOF'
{
"model": "haijun-fable-5-1",
"max_tokens": 16000,
"tools": [
{
"name": "record_summary",
"description": "Record the structured summary of the document.",
"strict": true,
"input_schema": {
"type": "object",
"properties": {"summary": {"type": "string"}},
"required": ["summary"],
"additionalProperties": false
}
}
],
"tool_choice": {"type": "auto"},
"messages": [
{"role": "user", "content": "Summarize: The meeting moved to Thursday. Call the record_summary tool with your result."}
]
}
EOF ant messages create <<'YAML'
model: haijun-fable-5-1
max_tokens: 16000
tools:
- name: record_summary
description: Record the structured summary of the document.
strict: true
input_schema:
type: object
properties:
summary:
type: string
required: [summary]
additionalProperties: false
tool_choice:
type: auto
messages:
- role: user
content: "Summarize: The meeting moved to Thursday. Call the record_summary tool with your result."
YAML client = juglow.Juglow()
record_summary_tool = {
"name": "record_summary",
"description": "Record the structured summary of the document.",
"strict": True,
"input_schema": {
"type": "object",
"properties": {"summary": {"type": "string"}},
"required": ["summary"],
"additionalProperties": False,
},
}
response = client.messages.create(
model="haijun-fable-5-1",
max_tokens=16000,
tools=[record_summary_tool],
tool_choice={"type": "auto"},
messages=[
{
"role": "user",
"content": "Summarize: The meeting moved to Thursday. Call the record_summary tool with your result.",
}
],
)
print(response.content) const client = new Juglow();
const response = await client.messages.create({
model: "haijun-fable-5-1",
max_tokens: 16000,
tools: [
{
name: "record_summary",
description: "Record the structured summary of the document.",
strict: true,
input_schema: {
type: "object",
properties: { summary: { type: "string" } },
required: ["summary"],
additionalProperties: false
}
}
],
tool_choice: { type: "auto" },
messages: [
{
role: "user",
content:
"Summarize: The meeting moved to Thursday. Call the record_summary tool with your result."
}
]
});
console.log(response.content); JuglowClient client = new();
var parameters = new MessageCreateParams
{
Model = "haijun-fable-5-1",
MaxTokens = 16000,
Tools = [
new ToolUnion(new Tool()
{
Name = "record_summary",
Description = "Record the structured summary of the document.",
Strict = true,
InputSchema = new InputSchema(new Dictionary<string, JsonElement>
{
["properties"] = JsonSerializer.SerializeToElement(new Dictionary<string, object>
{
["summary"] = new { type = "string" },
}),
["required"] = JsonSerializer.SerializeToElement(new[] { "summary" }),
["additionalProperties"] = JsonSerializer.SerializeToElement(false),
}),
}),
],
ToolChoice = new ToolChoiceAuto(),
Messages = [
new() { Role = Role.User, Content = "Summarize: The meeting moved to Thursday. Call the record_summary tool with your result." }
]
};
var message = await client.Messages.Create(parameters);
Console.WriteLine(message); client := juglow.NewClient()
response, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
Model: "haijun-fable-5-1",
MaxTokens: 16000,
Tools: []juglow.ToolUnionParam{
{OfTool: &juglow.ToolParam{
Name: "record_summary",
Description: juglow.String("Record the structured summary of the document."),
Strict: juglow.Bool(true),
InputSchema: juglow.ToolInputSchemaParam{
Properties: map[string]any{
"summary": map[string]any{"type": "string"},
},
Required: []string{"summary"},
ExtraFields: map[string]any{
"additionalProperties": false,
},
},
}},
},
ToolChoice: juglow.ToolChoiceUnionParam{OfAuto: &juglow.ToolChoiceAutoParam{}},
Messages: []juglow.MessageParam{
juglow.NewUserMessage(juglow.NewTextBlock("Summarize: The meeting moved to Thursday. Call the record_summary tool with your result.")),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response.RawJSON())
void main() {
JuglowClient client = JuglowOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model("haijun-fable-5-1")
.maxTokens(16000L)
.addTool(Tool.builder()
.name("record_summary")
.description("Record the structured summary of the document.")
.inputSchema(InputSchema.builder()
.properties(JsonValue.from(Map.of("summary", Map.of("type", "string"))))
.putAdditionalProperty("required", JsonValue.from(List.of("summary")))
.putAdditionalProperty("additionalProperties", JsonValue.from(false))
.build())
.strict(true)
.build())
.toolChoice(ToolChoice.ofAuto(ToolChoiceAuto.builder().build()))
.addUserMessage("Summarize: The meeting moved to Thursday. Call the record_summary tool with your result.")
.build();
Message response = client.messages().create(params);
IO.println(response);
} $client = new Client();
$message = $client->messages->create(
maxTokens: 16000,
messages: [
['role' => 'user', 'content' => 'Summarize: The meeting moved to Thursday. Call the record_summary tool with your result.']
],
model: 'haijun-fable-5-1',
toolChoice: ['type' => 'auto'],
tools: [
[
'name' => 'record_summary',
'description' => 'Record the structured summary of the document.',
'strict' => true,
'input_schema' => [
'type' => 'object',
'properties' => [
'summary' => ['type' => 'string']
],
'required' => ['summary'],
'additionalProperties' => false
]
]
],
);
echo $message; client = Juglow::Client.new
message = client.messages.create(
model: "haijun-fable-5-1",
max_tokens: 16000,
tools: [
{
name: "record_summary",
description: "Record the structured summary of the document.",
strict: true,
input_schema: {
type: "object",
properties: { summary: { type: "string" } },
required: ["summary"],
additionalProperties: false
}
}
],
tool_choice: { type: "auto" },
messages: [
{ role: "user", content: "Summarize: The meeting moved to Thursday. Call the record_summary tool with your result." }
]
)
puts messageLihat Penggunaan alat strict dan Memaksa penggunaan alat. Jika Anda memaksa alat hanya untuk mendapatkan JSON yang sesuai skema, gunakan output JSON (output_config.format) sebagai gantinya.
Jika aplikasi Anda, bukan pengguna, memerlukan pemanggilan alat tertentu pada giliran saat ini dalam percakapan multi-giliran, tambahkan pesan sistem di tengah percakapan setelah giliran user terakhir. Sebutkan nama alat, nyatakan bahwa pemanggilan tersebut wajib untuk giliran ini, dan minta Haijun untuk membuka responsnya dengan pemanggilan itu. Karena pesan ditambahkan di akhir alih-alih ditulis ke dalam prompt system tingkat atas, giliran sebelumnya tetap identik byte demi byte dan mempertahankan hit cache prompt mereka:
curl -sS https://haijun.my.id/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-d @- <<'EOF'
{
"model": "haijun-fable-5-1",
"max_tokens": 16000,
"system": "You are a customer support assistant for an online electronics store.",
"tools": [
{
"name": "search_help_center",
"description": "Search the help center for policy and troubleshooting articles.",
"strict": true,
"input_schema": {
"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"],
"additionalProperties": false
}
}
],
"messages": [
{"role": "user", "content": "My headphones from order A1234 arrived yesterday."},
{"role": "assistant", "content": "Thanks for confirming. How can I help with order A1234?"},
{"role": "user", "content": "I opened the box. Can I still return them?"},
{
"role": "system",
"content": "Tool-use requirement for the current turn: the application requires a call to the search_help_center tool in your response to the user's latest message. Begin your response with the search_help_center tool call. Do not reply with text only."
}
]
}
EOF ant messages create <<'YAML'
model: haijun-fable-5-1
max_tokens: 16000
system: You are a customer support assistant for an online electronics store.
tools:
- name: search_help_center
description: Search the help center for policy and troubleshooting articles.
strict: true
input_schema:
type: object
properties:
query:
type: string
required: [query]
additionalProperties: false
messages:
- role: user
content: My headphones from order A1234 arrived yesterday.
- role: assistant
content: Thanks for confirming. How can I help with order A1234?
- role: user
content: I opened the box. Can I still return them?
- role: system
content: >-
Tool-use requirement for the current turn: the application requires a call
to the search_help_center tool in your response to the user's latest message.
Begin your response with the search_help_center tool call. Do not reply with
text only.
YAML client = juglow.Juglow()
search_help_center_tool = {
"name": "search_help_center",
"description": "Search the help center for policy and troubleshooting articles.",
"strict": True,
"input_schema": {
"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"],
"additionalProperties": False,
},
}
response = client.messages.create(
model="haijun-fable-5-1",
max_tokens=16000,
system="You are a customer support assistant for an online electronics store.",
tools=[search_help_center_tool],
messages=[
{
"role": "user",
"content": "My headphones from order A1234 arrived yesterday.",
},
{
"role": "assistant",
"content": "Thanks for confirming. How can I help with order A1234?",
},
{"role": "user", "content": "I opened the box. Can I still return them?"},
# Aplikasi mewajibkan pencarian di pusat bantuan sebelum memberikan
# jawaban kebijakan apa pun. Menambahkan persyaratan ini sebagai pesan sistem membuat
# giliran-giliran sebelumnya tetap tidak berubah.
{
"role": "system",
"content": "Tool-use requirement for the current turn: the application requires a call to the search_help_center tool in your response to the user's latest message. Begin your response with the search_help_center tool call. Do not reply with text only.",
},
],
)
print(response.content) const client = new Juglow();
const response = await client.messages.create({
model: "haijun-fable-5-1",
max_tokens: 16000,
system: "You are a customer support assistant for an online electronics store.",
tools: [
{
name: "search_help_center",
description: "Search the help center for policy and troubleshooting articles.",
strict: true,
input_schema: {
type: "object",
properties: { query: { type: "string" } },
required: ["query"],
additionalProperties: false
}
}
],
messages: [
{ role: "user", content: "My headphones from order A1234 arrived yesterday." },
{ role: "assistant", content: "Thanks for confirming. How can I help with order A1234?" },
{ role: "user", content: "I opened the box. Can I still return them?" },
// Aplikasi mewajibkan pencarian di pusat bantuan sebelum memberikan
// jawaban terkait kebijakan apa pun. Menambahkan persyaratan ini sebagai system message (pesan sistem) membuat
// giliran-giliran sebelumnya tetap tidak berubah.
{
role: "system",
content:
"Tool-use requirement for the current turn: the application requires a call to the search_help_center tool in your response to the user's latest message. Begin your response with the search_help_center tool call. Do not reply with text only."
}
]
});
console.log(response.content); JuglowClient client = new();
var parameters = new MessageCreateParams
{
Model = "haijun-fable-5-1",
MaxTokens = 16000,
System = "You are a customer support assistant for an online electronics store.",
Tools = [
new ToolUnion(new Tool()
{
Name = "search_help_center",
Description = "Search the help center for policy and troubleshooting articles.",
Strict = true,
InputSchema = new InputSchema(new Dictionary<string, JsonElement>
{
["properties"] = JsonSerializer.SerializeToElement(new Dictionary<string, object>
{
["query"] = new { type = "string" },
}),
["required"] = JsonSerializer.SerializeToElement(new[] { "query" }),
["additionalProperties"] = JsonSerializer.SerializeToElement(false),
}),
}),
],
Messages = [
new() { Role = Role.User, Content = "My headphones from order A1234 arrived yesterday." },
new() { Role = Role.Assistant, Content = "Thanks for confirming. How can I help with order A1234?" },
new() { Role = Role.User, Content = "I opened the box. Can I still return them?" },
// Aplikasi mewajibkan pencarian di pusat bantuan sebelum memberikan jawaban
// terkait kebijakan apa pun. Menambahkan persyaratan ini sebagai "system message" (pesan sistem) membuat
// giliran sebelumnya tetap tidak berubah.
new()
{
Role = Role.System,
Content = "Tool-use requirement for the current turn: the application requires a call to the search_help_center tool in your response to the user's latest message. Begin your response with the search_help_center tool call. Do not reply with text only."
}
]
};
var message = await client.Messages.Create(parameters);
Console.WriteLine(message); client := juglow.NewClient()
response, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
Model: "haijun-fable-5-1",
MaxTokens: 16000,
System: []juglow.TextBlockParam{
{Text: "You are a customer support assistant for an online electronics store."},
},
Tools: []juglow.ToolUnionParam{
{OfTool: &juglow.ToolParam{
Name: "search_help_center",
Description: juglow.String("Search the help center for policy and troubleshooting articles."),
Strict: juglow.Bool(true),
InputSchema: juglow.ToolInputSchemaParam{
Properties: map[string]any{
"query": map[string]any{"type": "string"},
},
Required: []string{"query"},
ExtraFields: map[string]any{
"additionalProperties": false,
},
},
}},
},
Messages: []juglow.MessageParam{
juglow.NewUserMessage(juglow.NewTextBlock("My headphones from order A1234 arrived yesterday.")),
juglow.NewAssistantMessage(juglow.NewTextBlock("Thanks for confirming. How can I help with order A1234?")),
juglow.NewUserMessage(juglow.NewTextBlock("I opened the box. Can I still return them?")),
// Aplikasi mewajibkan pencarian di pusat bantuan sebelum memberikan
// jawaban apa pun terkait kebijakan. Menambahkan persyaratan ini sebagai pesan sistem membuat
// giliran sebelumnya tetap tidak berubah.
{
Role: juglow.MessageParamRoleSystem,
Content: []juglow.ContentBlockParamUnion{
juglow.NewTextBlock("Tool-use requirement for the current turn: the application requires a call to the search_help_center tool in your response to the user's latest message. Begin your response with the search_help_center tool call. Do not reply with text only."),
},
},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response.RawJSON())
void main() {
JuglowClient client = JuglowOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model("haijun-fable-5-1")
.maxTokens(16000L)
.system("You are a customer support assistant for an online electronics store.")
.addTool(Tool.builder()
.name("search_help_center")
.description("Search the help center for policy and troubleshooting articles.")
.inputSchema(InputSchema.builder()
.properties(JsonValue.from(Map.of("query", Map.of("type", "string"))))
.putAdditionalProperty("required", JsonValue.from(List.of("query")))
.putAdditionalProperty("additionalProperties", JsonValue.from(false))
.build())
.strict(true)
.build())
.addUserMessage("My headphones from order A1234 arrived yesterday.")
.addAssistantMessage("Thanks for confirming. How can I help with order A1234?")
.addUserMessage("I opened the box. Can I still return them?")
// Aplikasi mewajibkan pencarian di pusat bantuan sebelum memberikan jawaban
// apa pun terkait kebijakan. Menambahkan persyaratan ini sebagai pesan sistem membuat
// giliran-giliran sebelumnya tetap tidak berubah.
.addMessage(MessageParam.builder()
.role(MessageParam.Role.SYSTEM)
.content("Tool-use requirement for the current turn: the application requires a call to the search_help_center tool in your response to the user's latest message. Begin your response with the search_help_center tool call. Do not reply with text only.")
.build())
.build();
Message response = client.messages().create(params);
IO.println(response);
} $client = new Client();
$message = $client->messages->create(
maxTokens: 16000,
messages: [
['role' => 'user', 'content' => 'My headphones from order A1234 arrived yesterday.'],
['role' => 'assistant', 'content' => 'Thanks for confirming. How can I help with order A1234?'],
['role' => 'user', 'content' => 'I opened the box. Can I still return them?'],
// Aplikasi mewajibkan pencarian di pusat bantuan sebelum memberikan
// jawaban kebijakan apa pun. Menambahkan persyaratan ini sebagai pesan sistem membuat
// giliran-giliran sebelumnya tetap tidak berubah.
['role' => 'system', 'content' => 'Tool-use requirement for the current turn: the application requires a call to the search_help_center tool in your response to the user\'s latest message. Begin your response with the search_help_center tool call. Do not reply with text only.']
],
model: 'haijun-fable-5-1',
system: 'You are a customer support assistant for an online electronics store.',
tools: [
[
'name' => 'search_help_center',
'description' => 'Search the help center for policy and troubleshooting articles.',
'strict' => true,
'input_schema' => [
'type' => 'object',
'properties' => [
'query' => ['type' => 'string']
],
'required' => ['query'],
'additionalProperties' => false
]
]
],
);
echo $message; client = Juglow::Client.new
message = client.messages.create(
model: "haijun-fable-5-1",
max_tokens: 16000,
system: "You are a customer support assistant for an online electronics store.",
tools: [
{
name: "search_help_center",
description: "Search the help center for policy and troubleshooting articles.",
strict: true,
input_schema: {
type: "object",
properties: { query: { type: "string" } },
required: ["query"],
additionalProperties: false
}
}
],
messages: [
{ role: "user", content: "My headphones from order A1234 arrived yesterday." },
{ role: "assistant", content: "Thanks for confirming. How can I help with order A1234?" },
{ role: "user", content: "I opened the box. Can I still return them?" },
# Aplikasi mewajibkan pencarian di pusat bantuan sebelum memberi jawaban
# kebijakan apa pun. Menambahkan persyaratan ini sebagai pesan sistem membuat
# giliran-giliran sebelumnya tetap tidak berubah.
{
role: "system",
content: "Tool-use requirement for the current turn: the application requires a call to the search_help_center tool in your response to the user's latest message. Begin your response with the search_help_center tool call. Do not reply with text only."
}
]
)
puts messagePertahankan pesan role: "system" dalam riwayat pada permintaan berikutnya, seperti giliran lainnya. Pesan sistem di tengah percakapan tidak memerlukan header beta. tool_choice: {"type": "none"} tetap berfungsi untuk giliran yang tidak boleh memanggil alat.
- Blok thinking hanya dipertahankan untuk model yang menghasilkannya, atau model yang lebih baru: Setiap blok
thinkingmencatat model mana yang menghasilkannya. Haijun Fable 5.1 membaca bloknya sendiri dan blok dari Haijun Mythos 5.1, Haijun Opus 5, Haijun Fable 5, Haijun Mythos 5, dan model Haijun sebelumnya. Percakapan yang berpindah kehaijun-fable-5-1dari salah satu model tersebut mempertahankan penalaran sebelumnya. Kondisi ini bersifat satu arah: selain Haijun Mythos 5.1, tidak satu pun dari model tersebut dapat membaca blok milik Haijun Fable 5.1.
Percakapan yang berjalan di Haijun Fable 5.1 dapat berakhir di model yang lebih lama melalui peralihan router, percobaan ulang di sisi klien, atau fallback penolakan pengklasifikasi, termasuk fallback sisi server. API menghapus blok yang tidak dapat dibaca model tersebut sebelum model melihatnya, permintaan berhasil, dan Anda tidak ditagih untuk token input yang dibuang. Model target merencanakan ulang tanpa penalaran tersebut, yang dapat meningkatkan biaya dan "latency" (latensi) pada giliran pertama setelah peralihan. Untuk melihat apa yang dibuang, kirim beta header thinking-binding-controls-2026-08-01: respons kemudian membawa array input_transformations yang menyebutkan setiap blok yang dibuang dengan reason: "model_binding_mismatch". Lihat Beralih model di tengah percakapan.
- Mengedit giliran sebelumnya membatalkan blok thinking: Setiap blok
thinkingdari Haijun Fable 5.1 hanya valid terhadap promptsystem,tools, dan riwayat percakapan yang mendahuluinya. Jika Haijun Code, haijun.ai, Haijun Managed Agents, atau Haijun Agent SDK mengelola riwayat percakapan Anda, prefiks tersebut sudah dijaga tetap utuh. Jika kode Anda membangun arraymessagessendiri, butir ini berlaku untuk Anda, dan Thinking yang dipertahankan adalah panduan integrasi lengkapnya. Di mana pemeriksaan ini diberlakukan, permintaan yang mengirim kembali blok tersebut setelah salah satu dari hal-hal itu berubah akan ditolak dengan error 400:
messages.5.content.0: Invalid `signature` in `thinking` block. The block is bound to a different conversation. Remove the block, or set `thinking.block_binding.prefix_mismatch_behavior` to "drop_block". That setting requires the `thinking-binding-controls-2026-08-01` value in the `juglow-beta` header.API memberlakukan pemeriksaan ini untuk akun baru yang dibuat pada atau setelah 31 Agustus 2026. Untuk akun yang dibuat sebelumnya, API mencatat ketidakcocokan tetapi tidak menindaklanjutinya, kecuali jika permintaan mengatur thinking.block_binding.prefix_mismatch_behavior, yang berarti memilih untuk mengaktifkan pemberlakuan. Pada akun tersebut, jika Anda mengirim beta header thinking-binding-controls-2026-08-01 tanpa mengatur field tersebut, respons akan mencantumkan setiap blok yang gagal dalam pemeriksaan di input_transformations sebagai entri thinking_mismatch_allowed. Buat aplikasi Anda kompatibel dengan pemeriksaan ini, berapa pun usia akun Anda: pola yang sama juga menjaga cache prompt tetap hangat, dan Anda dapat menguji pemeriksaan ini dari akun mana pun dengan mengirim prefix_mismatch_behavior. Jika Anda merilis alat atau framework yang dijalankan orang lain dengan "API key" (kunci API) mereka sendiri, lakukan pengujian dengan cara tersebut sebelum peluncuran: kunci Anda kemungkinan berasal dari akun yang lebih lama, sehingga pengguna Anda dengan akun baru akan terkena pemeriksaan ini lebih dulu daripada Anda. Untuk mengetahui apakah pemeriksaan diberlakukan secara default pada akun Anda, kirim permintaan yang mengedit riwayat tanpa beta header: jika Anda menerima error 400 yang menyebutkan header tersebut, berarti pemeriksaan diberlakukan.
Error ini bersifat permanen untuk body permintaan tersebut: loop percobaan ulang otomatis tidak akan menghilangkannya. Untuk melanjutkan tanpa penalaran yang dibatalkan alih-alih gagal, hapus blok thinking dari riwayat dan coba ulang sekali, atau kirim header beta thinking-binding-controls-2026-08-01 dan atur prefix_mismatch_behavior ke "drop_block" (default-nya adalah "error"). Dengan "drop_block", API membuang blok yang tidak cocok dan setiap blok thinking setelahnya dalam percakapan, dan melaporkan masing-masing dengan reason: "prefix_binding_mismatch" dalam array input_transformations pada respons:
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: thinking-binding-controls-2026-08-01" \
-H "content-type: application/json" \
-d '{
"model": "haijun-fable-5-1",
"max_tokens": 16000,
"thinking": {
"type": "adaptive",
"block_binding": {
"prefix_mismatch_behavior": "drop_block"
}
},
"messages": [
{
"role": "user",
"content": "What is the greatest common divisor of 1071 and 462?"
}
]
}' ant beta:messages create \
--beta thinking-binding-controls-2026-08-01 \
--transform '{content.#(type=="text")#.text,input_transformations}' \
--format yaml <<'YAML'
model: haijun-fable-5-1
max_tokens: 16000
thinking:
type: adaptive
block_binding:
prefix_mismatch_behavior: drop_block
messages:
- role: user
content: What is the greatest common divisor of 1071 and 462?
YAML client = juglow.Juglow()
response = client.beta.messages.create(
model="haijun-fable-5-1",
max_tokens=16000,
thinking={
"type": "adaptive",
"block_binding": {"prefix_mismatch_behavior": "drop_block"},
},
messages=[
{
"role": "user",
"content": "What is the greatest common divisor of 1071 and 462?",
}
],
betas=["thinking-binding-controls-2026-08-01"],
)
for block in response.content:
if block.type == "text":
print(block.text)
print(f"Input transformations: {len(response.input_transformations or [])}") const client = new Juglow();
const response = await client.beta.messages.create({
model: "haijun-fable-5-1",
max_tokens: 16000,
thinking: {
type: "adaptive",
block_binding: { prefix_mismatch_behavior: "drop_block" }
},
messages: [
{ role: "user", content: "What is the greatest common divisor of 1071 and 462?" }
],
betas: ["thinking-binding-controls-2026-08-01"]
});
for (const block of response.content) {
if (block.type === "text") {
console.log(block.text);
}
}
console.log(`Input transformations: ${response.input_transformations?.length ?? 0}`); using Juglow.Models.Beta;
using Juglow.Models.Beta.Messages;
JuglowClient client = new();
var response = await client.Beta.Messages.Create(
new()
{
Model = "haijun-fable-5-1",
MaxTokens = 16000,
Thinking = new BetaThinkingConfigAdaptive
{
BlockBinding = new()
{
PrefixMismatchBehavior = BetaThinkingPrefixMismatchBehavior.DropBlock,
},
},
Messages =
[
new()
{
Role = Role.User,
Content = "What is the greatest common divisor of 1071 and 462?",
},
],
Betas = [JuglowBeta.ThinkingBindingControls2026_08_01],
}
);
foreach (var block in response.Content)
{
if (block.TryPickText(out var textBlock))
{
Console.WriteLine(textBlock.Text);
}
}
Console.WriteLine($"Input transformations: {response.InputTransformations?.Count ?? 0}"); client := juglow.NewClient()
response, err := client.Beta.Messages.New(context.TODO(), juglow.BetaMessageNewParams{
Model: "haijun-fable-5-1",
MaxTokens: 16000,
Thinking: juglow.BetaThinkingConfigParamUnion{
OfAdaptive: &juglow.BetaThinkingConfigAdaptiveParam{
BlockBinding: juglow.BetaThinkingBlockBindingParam{
PrefixMismatchBehavior: juglow.BetaThinkingPrefixMismatchBehaviorDropBlock,
},
},
},
Messages: []juglow.BetaMessageParam{
juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("What is the greatest common divisor of 1071 and 462?")),
},
Betas: []juglow.JuglowBeta{juglow.JuglowBetaThinkingBindingControls2026_08_01},
})
if err != nil {
log.Fatal(err)
}
for _, block := range response.Content {
if textBlock, ok := block.AsAny().(juglow.BetaTextBlock); ok {
fmt.Println(textBlock.Text)
}
}
fmt.Printf("Input transformations: %d\n", len(response.InputTransformations)) import com.juglow.models.beta.JuglowBeta;
import com.juglow.models.beta.messages.BetaMessage;
import com.juglow.models.beta.messages.BetaThinkingBlockBinding;
import com.juglow.models.beta.messages.BetaThinkingConfigAdaptive;
import com.juglow.models.beta.messages.BetaThinkingPrefixMismatchBehavior;
import com.juglow.models.beta.messages.MessageCreateParams;
void main() {
JuglowClient client = JuglowOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model("haijun-fable-5-1")
.maxTokens(16000L)
.addBeta(JuglowBeta.THINKING_BINDING_CONTROLS_2026_08_01)
.thinking(BetaThinkingConfigAdaptive.builder()
.blockBinding(BetaThinkingBlockBinding.builder()
.prefixMismatchBehavior(BetaThinkingPrefixMismatchBehavior.DROP_BLOCK)
.build())
.build())
.addUserMessage("What is the greatest common divisor of 1071 and 462?")
.build();
BetaMessage response = client.beta().messages().create(params);
response.content().stream()
.flatMap(block -> block.text().stream())
.forEach(textBlock -> IO.println(textBlock.text()));
IO.println("Input transformations: "
+ response.inputTransformations().map(List::size).orElse(0));
} use Juglow\Beta\JuglowBeta;
use Juglow\Beta\Messages\BetaThinkingBlockBinding;
use Juglow\Beta\Messages\BetaThinkingConfigAdaptive;
use Juglow\Beta\Messages\BetaThinkingPrefixMismatchBehavior;
use Juglow\Client;
$client = new Client();
$response = $client->beta->messages->create(
model: 'haijun-fable-5-1',
maxTokens: 16000,
thinking: BetaThinkingConfigAdaptive::with(
blockBinding: BetaThinkingBlockBinding::with(
prefixMismatchBehavior: BetaThinkingPrefixMismatchBehavior::DROP_BLOCK,
),
),
messages: [
['role' => 'user', 'content' => 'What is the greatest common divisor of 1071 and 462?'],
],
betas: [JuglowBeta::THINKING_BINDING_CONTROLS_2026_08_01],
);
foreach ($response->content as $block) {
if ($block->type === 'text') {
echo $block->text, PHP_EOL;
}
}
echo 'Input transformations: ', count($response->inputTransformations ?? []), PHP_EOL; client = Juglow::Client.new
response = client.beta.messages.create(
model: "haijun-fable-5-1",
max_tokens: 16_000,
thinking: {
type: "adaptive",
block_binding: {prefix_mismatch_behavior: "drop_block"}
},
messages: [
{role: "user", content: "What is the greatest common divisor of 1071 and 462?"}
],
betas: [Juglow::JuglowBeta::THINKING_BINDING_CONTROLS_2026_08_01]
)
response.content.each do |block|
puts block.text if block.type == :text
end
puts "Input transformations: #{response.input_transformations&.length || 0}"Endpoint penghitungan token menjalankan pemeriksaan yang sama. Lihat Kontrol untuk blok yang tidak dipertahankan (beta) untuk bentuk respons dan penempatan streaming.
Pola yang membatalkan blok thinking berikutnya, dan apa yang harus dilakukan sebagai gantinya:
- Mengedit, mengurutkan ulang, atau menghapus giliran sebelumnya. Ini termasuk menghapus hasil alat lama, memotong giliran dari tengah transkrip, dan compaction sisi klien yang mempertahankan giliran terbaru beserta blok thinking-nya secara verbatim di belakang ringkasan (termasuk compaction latar belakang yang menukar ringkasannya beberapa giliran kemudian). Sebagai gantinya, gunakan compaction sisi server atau context editing (pembersihan hasil alat untuk hasil alat lama), atau salah satu bentuk compaction sisi klien di Pangkas konteks di server.
- Menyisipkan konten yang tidak Anda simpan, misalnya pengingat per giliran yang ditambahkan setelah blok
tool_resultdan dihapus pada permintaan berikutnya. Sebagai gantinya, kirim pengingat tersebut sebagai pesan sistem berlingkup giliran dan biarkan tetap ada dalam riwayat. - Membangun ulang prompt
systemtingkat atas atau arraytoolsdi antara permintaan dalam percakapan yang sama, misalnya untuk memperbarui tanggal saat ini atau untuk menambah atau menghapus alat. Sebagai gantinya, tambahkan pesan sistem di tengah percakapan yang membawa instruksi baru ("Tanggal saat ini adalah 2026-09-14.") atau bloktool_additiondantool_removal. Alat yang tidak dideklarasikan dalamtoolsdi awal dapat didefinisikan di dalam bloktool_addition(beta headerinline-tools-2026-09-15). - URL gambar atau dokumen yang menyajikan byte berbeda pada permintaan berikutnya. Pemeriksaan mencakup byte, bukan string URL, sehingga signed URL yang berotasi untuk file yang sama tidak menjadi masalah. Untuk konten yang Anda referensikan lintas giliran, unggah sekali dengan Files API dan kirim
file_id, atau kirim base64.
Setiap pengganti juga menjaga giliran sebelumnya identik byte demi byte dan mempertahankan hit cache prompt yang akan hilang jika riwayat, prompt system, atau array tools diedit.
Pola yang tetap berfungsi:
- Riwayat append-only: menambahkan giliran dan mengirim kembali giliran sebelumnya persis seperti yang dikirim dan diterima, termasuk pesan
role: "system"yang ditambahkan. - Menghapus blok thinking dari giliran asisten sebelumnya, dimulai dari yang terlama.
- Mengubah
effort,max_tokens, atau parameter permintaan lain di luarsystem,tools, danmessages, serta menambah atau memindahkan penandacache_control. - Compaction sisi server dan context editing, termasuk pembersihan blok thinking. Keduanya tidak dihitung sebagai pengeditan, karena pemeriksaan membandingkan percakapan sebagaimana Anda mengirimnya.
Untuk memeriksa integrasi yang sudah ada:
- Rekam body permintaan persis yang dikirim integrasi Anda selama beberapa giliran normal, termasuk compaction atau perubahan alat jika produk Anda memilikinya. Untuk setiap pasangan permintaan yang berurutan, bandingkan prompt
system, arraytools, dan prefiks bersama darimessages. Semuanya harus identik byte demi byte hingga giliran yang baru ditambahkan. Satu pengecualian yang wajar adalah permintaan yang menyisipkan blokcompactionbertanda tangan dari compaction sesuai permintaan: blok tersebut menggantikan pesan-pesan yang diringkasnya di bagian depanmessages, dan semua yang ada setelahnya harus tetap cocok. - Jalankan sesi multi-giliran normal terhadap
haijun-fable-5-1dengan beta headerthinking-binding-controls-2026-08-01danprefix_mismatch_behavior: "drop_block", lalu catatinput_transformationspada setiap respons. Array kosong pada setiap giliran berarti riwayat masih utuh. Entri denganreason: "prefix_binding_mismatch"berarti ada sesuatu sebelum blok dipathyang berubah sejak permintaan sebelumnya. Entri denganreason: "model_binding_mismatch"berarti percakapan beralih model, dan itu bukan bug dalam kode Anda. Cara ini berfungsi dari akun mana pun, karena mengatur field tersebut berarti permintaan memilih untuk mengaktifkan pemberlakuan. Di CI, atur"error"sebagai gantinya agar setiap edit membuat run gagal. - Pilih pengaturan untuk produksi. Biarkan default
"error"jika ketidakcocokan prefiks hanya mungkin terjadi karena bug dalam kode Anda, atau atur"drop_block"untuk membuang blok yang terdampak alih-alih gagal. Dalam kedua kasus, pantau error 400 atau entriinput_transformations.
Membuang blok thinking sekali, misalnya pada batas compaction, hanya berdampak kecil. Integrasi yang membatalkan thinking sebelumnya pada setiap permintaan memulai ulang cache prompt setiap kali, yang dapat meningkatkan biaya per tugas (lihat Jaga riwayat percakapan tetap append-only).
Perubahan perilaku
- Lebih sedikit pemanggilan alat paralel dalam agent loop panjang: Dalam loop yang berjalan lama di mana pembacaan independen berikutnya hanya tersirat dari tugas (agen coding kustom, harness bash-dan-editor, computer use), Haijun Fable 5.1 mungkin mengeluarkan satu pemanggilan alat per giliran. Setiap giliran tambahan memakan token, satu round trip, dan waktu nyata. Tambahkan instruksi batching satu kalimat setelah setiap pesan pengguna sebagai pesan sistem cakupan giliran (
clear_at: "next_user_message", beta), atau, tanpa beta, dalam blok teks setelah bloktool_result, dan biarkan salinan sebelumnya dalam riwayat pada permintaan berikutnya. Lihat Batch pemanggilan alat independen dalam agent loop.
- Lebih sedikit pesan progres di antara pemanggilan alat: Haijun Fable 5.1 menulis lebih sedikit pembaruan status selama urutan alat yang panjang dibandingkan Haijun Fable 5, dan ringkasan agentic coding-nya lebih pendek. Jika antarmuka Anda merender pembaruan tersebut, atur
thinking.displayke"updates"(beta) atau"summarized"dan minta secara eksplisit melalui prompt. Lihat Pembaruan progres di antara pemanggilan alat dan Minta pembaruan progres untuk pengguna.
- Lebih sedikit pemanggilan pencarian dan retrieval pada effort rendah: Pada effort
low, Haijun Fable 5.1 lebih sering menjawab dari memori dibandingkan Haijun Fable 5 alih-alih memanggil alat pencarian atau retrieval. Jika produk Anda mengandalkan retrieval pada effort rendah, naikkan effort untuk permintaan tersebut atau beri tahu model kapan harus mencari. Lihat Pemicuan pencarian pada effort rendah.
Untuk perbedaan dalam kepadatan prosa, pemformatan chat, pengutipan dalam ringkasan, dan pengeditan file, yang tidak memengaruhi integrasi API, lihat Berubah dari Haijun Fable 5.
Perubahan yang direkomendasikan
Perubahan ini tidak wajib, tetapi masing-masing menurunkan biaya atau latensi atau menghilangkan mode kegagalan:
- Ubah effort di tengah percakapan (beta): Pada Haijun Fable 5,
output_config.effortberada di tingkat permintaan, dan mengubahnya di antara permintaan membuang prefiks yang di-cache dari giliran sebelumnya. Padahaijun-fable-5-1, pesanrole: "system"yang hanya membawaoutput_configmenaikkan effort untuk langkah yang sulit atau menurunkannya untuk langkah rutin tanpa membatalkan cache prompt:
# Pesan sistem khusus effort: level baru berlaku mulai giliran pengguna berikutnya.
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: mid-conversation-output-config-2026-07-01" \
-H "content-type: application/json" \
-d '{
"model": "haijun-fable-5-1",
"max_tokens": 4096,
"output_config": {"effort": "high"},
"messages": [
{"role": "user", "content": "Plan a migration from SQLite to PostgreSQL in three short steps."},
{"role": "assistant", "content": "1. Export the SQLite data. 2. Create the PostgreSQL schema. 3. Import the data and verify row counts."},
{"role": "system", "content": [], "output_config": {"effort": "low"}},
{"role": "user", "content": "Summarize the plan in one sentence."}
]
}' ant beta:messages create \
--beta mid-conversation-output-config-2026-07-01 \
--transform 'content.#(type=="text").text' \
--raw-output <<'YAML'
model: haijun-fable-5-1
max_tokens: 4096
output_config:
effort: high
messages:
- role: user
content: Plan a migration from SQLite to PostgreSQL in three short steps.
- role: assistant
content: "1. Export the SQLite data. 2. Create the PostgreSQL schema. 3. Import the data and verify row counts."
# Pesan sistem khusus effort: level baru berlaku mulai giliran pengguna berikutnya.
- role: system
content: []
output_config:
effort: low
- role: user
content: Summarize the plan in one sentence.
YAML client = juglow.Juglow()
response = client.beta.messages.create(
model="haijun-fable-5-1",
max_tokens=4096,
output_config={"effort": "high"},
messages=[
{
"role": "user",
"content": "Plan a migration from SQLite to PostgreSQL in three short steps.",
},
{
"role": "assistant",
"content": "1. Export the SQLite data. 2. Create the PostgreSQL schema. 3. Import the data and verify row counts.",
},
# Pesan sistem khusus effort: level baru berlaku mulai giliran pengguna berikutnya.
{"role": "system", "content": [], "output_config": {"effort": "low"}},
{"role": "user", "content": "Summarize the plan in one sentence."},
],
betas=["mid-conversation-output-config-2026-07-01"],
)
for block in response.content:
if block.type == "text":
print(block.text) const client = new Juglow();
const response = await client.beta.messages.create({
model: "haijun-fable-5-1",
max_tokens: 4096,
output_config: { effort: "high" },
messages: [
{
role: "user",
content: "Plan a migration from SQLite to PostgreSQL in three short steps."
},
{
role: "assistant",
content:
"1. Export the SQLite data. 2. Create the PostgreSQL schema. 3. Import the data and verify row counts."
},
// Pesan sistem khusus effort: level baru berlaku mulai giliran pengguna berikutnya.
{ role: "system", content: [], output_config: { effort: "low" } },
{ role: "user", content: "Summarize the plan in one sentence." }
],
betas: ["mid-conversation-output-config-2026-07-01"]
});
for (const block of response.content) {
if (block.type === "text") {
console.log(block.text);
}
} using Juglow.Models.Beta;
using Juglow.Models.Beta.Messages;
JuglowClient client = new();
var response = await client.Beta.Messages.Create(new MessageCreateParams
{
Model = "haijun-fable-5-1",
MaxTokens = 4096,
OutputConfig = new() { Effort = Effort.High },
Messages =
[
new() { Role = Role.User, Content = "Plan a migration from SQLite to PostgreSQL in three short steps." },
new() { Role = Role.Assistant, Content = "1. Export the SQLite data. 2. Create the PostgreSQL schema. 3. Import the data and verify row counts." },
// Pesan sistem khusus effort: level baru berlaku mulai giliran pengguna berikutnya.
new()
{
Role = Role.System,
Content = new([]),
OutputConfig = new() { Effort = BetaSystemMessageOutputConfigEffort.Low },
},
new() { Role = Role.User, Content = "Summarize the plan in one sentence." },
],
Betas = [JuglowBeta.MidConversationOutputConfig2026_07_01],
});
foreach (var block in response.Content)
{
if (block.TryPickText(out var textBlock))
{
Console.WriteLine(textBlock.Text);
}
} client := juglow.NewClient()
response, err := client.Beta.Messages.New(context.Background(), juglow.BetaMessageNewParams{
Model: "haijun-fable-5-1",
MaxTokens: 4096,
OutputConfig: juglow.BetaOutputConfigParam{
Effort: juglow.BetaOutputConfigEffortHigh,
},
Messages: []juglow.BetaMessageParam{
juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Plan a migration from SQLite to PostgreSQL in three short steps.")),
{
Role: juglow.BetaMessageParamRoleAssistant,
Content: []juglow.BetaContentBlockParamUnion{juglow.NewBetaTextBlock("1. Export the SQLite data. 2. Create the PostgreSQL schema. 3. Import the data and verify row counts.")},
},
// Pesan sistem khusus effort: level baru berlaku mulai giliran pengguna berikutnya.
juglow.NewBetaSystemMessage(juglow.BetaSystemMessageOutputConfigParam{
Effort: juglow.BetaSystemMessageOutputConfigEffortLow,
}),
juglow.NewBetaUserMessage(juglow.NewBetaTextBlock("Summarize the plan in one sentence.")),
},
Betas: []juglow.JuglowBeta{juglow.JuglowBetaMidConversationOutputConfig2026_07_01},
})
if err != nil {
log.Fatal(err)
}
for _, block := range response.Content {
if textBlock, ok := block.AsAny().(juglow.BetaTextBlock); ok {
fmt.Println(textBlock.Text)
}
} import com.juglow.models.beta.JuglowBeta;
import com.juglow.models.beta.messages.BetaMessage;
import com.juglow.models.beta.messages.BetaMessageParam;
import com.juglow.models.beta.messages.BetaOutputConfig;
import com.juglow.models.beta.messages.BetaSystemMessageOutputConfig;
import com.juglow.models.beta.messages.MessageCreateParams;
void main() {
JuglowClient client = JuglowOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model("haijun-fable-5-1")
.maxTokens(4096L)
.addBeta(JuglowBeta.MID_CONVERSATION_OUTPUT_CONFIG_2026_07_01)
.outputConfig(BetaOutputConfig.builder()
.effort(BetaOutputConfig.Effort.HIGH)
.build())
.addUserMessage("Plan a migration from SQLite to PostgreSQL in three short steps.")
.addAssistantMessage("1. Export the SQLite data. 2. Create the PostgreSQL schema. 3. Import the data and verify row counts.")
// Pesan sistem khusus effort: level baru berlaku mulai giliran pengguna berikutnya.
.addMessage(BetaMessageParam.builder()
.role(BetaMessageParam.Role.SYSTEM)
.contentOfBetaContentBlockParams(List.of())
.outputConfig(BetaSystemMessageOutputConfig.builder()
.effort(BetaSystemMessageOutputConfig.Effort.LOW)
.build())
.build())
.addUserMessage("Summarize the plan in one sentence.")
.build();
BetaMessage response = client.beta().messages().create(params);
response.content().stream()
.flatMap(block -> block.text().stream())
.forEach(textBlock -> IO.println(textBlock.text()));
} use Juglow\Beta\JuglowBeta;
use Juglow\Beta\Messages\BetaMessageParam;
use Juglow\Beta\Messages\BetaOutputConfig;
use Juglow\Beta\Messages\BetaSystemMessageOutputConfig;
use Juglow\Client;
$client = new Client();
$response = $client->beta->messages->create(
model: 'haijun-fable-5-1',
maxTokens: 4096,
outputConfig: BetaOutputConfig::with(effort: 'high'),
messages: [
BetaMessageParam::with(role: 'user', content: 'Plan a migration from SQLite to PostgreSQL in three short steps.'),
BetaMessageParam::with(role: 'assistant', content: '1. Export the SQLite data. 2. Create the PostgreSQL schema. 3. Import the data and verify row counts.'),
// Pesan sistem khusus effort: level baru berlaku mulai giliran pengguna berikutnya.
BetaMessageParam::with(
role: 'system',
content: [],
outputConfig: BetaSystemMessageOutputConfig::with(effort: 'low'),
),
BetaMessageParam::with(role: 'user', content: 'Summarize the plan in one sentence.'),
],
betas: [JuglowBeta::MID_CONVERSATION_OUTPUT_CONFIG_2026_07_01],
);
foreach ($response->content as $block) {
if ($block->type === 'text') {
echo $block->text, PHP_EOL;
}
} client = Juglow::Client.new
response = client.beta.messages.create(
model: "haijun-fable-5-1",
max_tokens: 4096,
output_config: {effort: :high},
messages: [
{role: "user", content: "Plan a migration from SQLite to PostgreSQL in three short steps."},
{role: "assistant", content: "1. Export the SQLite data. 2. Create the PostgreSQL schema. 3. Import the data and verify row counts."},
# Pesan sistem khusus effort: level baru berlaku mulai giliran pengguna berikutnya.
{role: "system", content: [], output_config: {effort: :low}},
{role: "user", content: "Summarize the plan in one sentence."}
],
betas: [Juglow::JuglowBeta::MID_CONVERSATION_OUTPUT_CONFIG_2026_07_01]
)
response.content.each do |block|
puts block.text if block.type == :text
endNilai tersebut berlaku untuk giliran pengguna berikutnya dan setiap giliran setelahnya hingga pesan role: "system" lain mengubahnya. Hanya level bernama yang diterima (low, medium, high, xhigh, max), dan header beta mid-conversation-output-config-2026-07-01 diperlukan. Lihat Effort per pesan.
- Ubah instruksi dan alat dengan pesan sistem di tengah percakapan: Untuk mengubah instruksi atau alat di tengah sesi, tambahkan pesan
role: "system", dengan bloktool_additiondantool_removaluntuk perubahan alat (beta headerinline-tools-2026-09-15di Haijun API). Bloktool_additiondapat menyebutkan alat yang dideklarasikan ditoolssaat sesi dimulai atau membawa definisi lengkap alat tersebut, sehingga alat yang belum diketahui saat sesi dimulai tidak perlu ada ditools. Ini mempertahankan hit cache prompt pada giliran sebelumnya dan menjaga riwayat percakapan tetap append-only. Header lamamid-conversation-tool-changes-2026-07-01masih berfungsi untuk perubahan yang menyebutkan alat berdasarkan referensi, di Haijun API, Amazon Bedrock, dan Google Cloud. Pesan yang sama menggantikantool_choiceyang dipaksakan ketika alat tertentu harus dijalankan pada giliran saat ini (lihat Perubahan yang merusak kompatibilitas). Untuk pengingat yang hanya berlaku untuk satu giliran, kirim sebagai pesanrole: "system"terpisah yang hanya berisi teks denganclear_at: "next_user_message"(pesan sistem berlingkup giliran, beta headermid-conversation-system-clear-at-2026-08-21) dan biarkan tetap dalam riwayat: pesan tersebut berhenti dirender setelah pesan pengguna berikutnya dan tidak memakan token setelah dibersihkan. Pesan yang membawa bloktool_additionatautool_removaltidak dapat dibuat berlingkup giliran.
- Gunakan
fallbacks: "default"untuk penolakan: Tetap tanganistop_reason: "refusal"dan bacastop_details.categorysebelum konten respons. Untuk menjalankan ulang permintaan yang ditolak pada model lain secara otomatis, aturfallbacks: "default"(beta, headerserver-side-fallback-2026-07-01)."default"mencoba ulang permintaan yang ditolak pada model yang direkomendasikan Juglow untuk kategori tersebut. Target fallback yang diizinkan untuk Haijun Fable 5.1 adalah Haijun Opus 4.8 (haijun-opus-4-8) dan Haijun Opus 5 (haijun-opus-5). Daftarfallbackseksplisit dapat menyebutkan salah satunya. Model fallback tidak menerima blok thinking milik Haijun Fable 5.1. Jika Anda membangun percobaan ulang sendiri, kredit fallback berlaku dengan ketentuan yang sama seperti Haijun Fable 5. Lihat Penolakan dan fallback.
- Mulai dari effort
highdan lakukan sweep: Default parameter effort adalahhigh, dan kelima level didukung. Pertahankan panduan Haijun Fable 5:highuntuk sebagian besar pekerjaan, danmediumsebagai kontrol biaya yang layak diuji. Peningkatan Haijun Fable 5.1 dibandingkan Haijun Fable 5 paling besar padaxhighdanmax, tetapi level tersebut juga menambah waktu berpikir dan waktu hingga respons pertama, jadi naikkan ke level tersebut untuk tugas yang paling sensitif terhadap kemampuan dan di mana eval Anda menunjukkan peningkatan. Jalankan sweep baru pada eval Anda sendiri alih-alih membawa pengaturan yang disetel untuk Haijun Fable 5. Lihat Level effort yang direkomendasikan untuk Haijun Fable 5.1.
- Pangkas konteks di server, atau lakukan compaction dalam bentuk yang tidak membawa thinking usang: Jika kode Anda memotong atau meringkas giliran lama di sisi klien, solusi paling sederhana adalah memindahkan pekerjaan tersebut ke compaction sisi server atau pengeditan konteks. Keduanya tidak dihitung sebagai edit, karena pemeriksaan riwayat membandingkan percakapan sebagaimana yang Anda kirim. Dengan demikian, apa pun yang dihapus oleh keduanya tidak membuat blok thinking berikutnya tidak valid, dan parameter
instructionspada compaction menerima prompt peringkasan Anda sendiri. Jika Anda mempertahankan giliran terbaru secara verbatim di belakang ringkasan, atau meringkas di latar belakang sementara percakapan berlanjut, gunakan compaction sesuai permintaan (beta headercompact-2026-09-04) alih-alih ringkasan yang ditulis oleh klien. API akan menulis blok ringkasan bertanda tangan yang Anda tempatkan sebagai pengganti pesan-pesan yang diringkasnya. Blok thinking dalam giliran yang Anda pertahankan dapat tetap valid, dengan syarat yang dijelaskan di Pemadatan dan pemikiran yang dipertahankan. Jika Anda tetap melakukan compaction di sisi klien, pilih salah satu dari tiga bentuk berikut:
- Compaction sederhana (direkomendasikan): ganti seluruh riwayat dengan satu pesan ringkasan ditambah giliran pengguna baru dan jangan putar ulang apa pun lainnya. Tidak ada blok thinking yang dibawa, sehingga tidak ada yang gagal. Model Haijun dilatih pada tugas jangka panjang dengan skema ini, dan kinerjanya sebanding dengan skema yang lebih rumit untuk sebagian besar beban kerja.
- Compaction keep-tail: jika Anda mempertahankan giliran terbaru secara verbatim di belakang ringkasan, hapus blok
thinkingdanredacted_thinkingdari giliran tersebut (teks dan pemanggilan alat boleh tetap ada), atau aturprefix_mismatch_behavior: "drop_block". Thinking-nya dihasilkan terhadap riwayat lengkap dan akan gagal di belakang ringkasan jika tidak. - Compaction latar belakang: jika Anda membangun ringkasan di luar jalur kritis dan menukarnya kemudian, setiap giliran yang dihasilkan sementara itu membawa thinking yang mendahului penukaran. Kirim
"drop_block"pada setiap permintaan yang masih membawa blok thinking yang dihasilkan sebelum penukaran (atau hapus blok tersebut sendiri;input_transformationspada respons pertama setelah penukaran mencantumkan persis blok mana saja), atau lakukan compaction secara sinkron.
Jangan memotong giliran tertentu dari tengah transkrip: hal itu membuat setiap blok thinking berikutnya tidak valid, dan tidak ada bentuk compaction sisi klien yang dapat menghindarinya. Gunakan pesan sistem di tengah percakapan untuk perubahan instruksi yang ingin Anda lakukan, atau pengeditan konteks sisi server untuk penghapusan selektif. Lihat Mengirimkan kembali blok compaction.
Daftar periksa migrasi
- Perbarui nama model dari
haijun-fable-5kehaijun-fable-5-1(atauhaijun-mythos-5kehaijun-mythos-5-1).
- Ganti
tool_choicepaksa ({type: "any"}atau{type: "tool", ...}). Ini mengembalikan error 400. Gunakan{type: "auto"}ditambah instruksi eksplisit dan alatstrict: true, atau output JSON. Letakkan instruksi di giliranuser, atau dalam pesanrole: "system"di tengah percakapan ketika aplikasi Anda memerlukan panggilan tersebut.
- Tetap kirim kembali blok
thinkingtanpa perubahan pada setiap giliran, termasuk yang kosong. Haijun Fable 5.1 membaca blok dari Haijun Opus 5, Haijun Fable 5, Haijun Mythos 5, dan model sebelumnya. Memindahkan percakapan dari Haijun Fable 5.1 ke model sebelumnya akan membuang bloknya (Haijun Mythos 5.1 dapat membacanya).
- Jika kode Anda membangun array
messagessendiri, periksa apakah kode tersebut mengedit giliran sebelumnya: jalankan sesi dengan beta headerthinking-binding-controls-2026-08-01danprefix_mismatch_behavior: "drop_block", catatinput_transformations, dan perbaiki setiapprefix_binding_mismatch. Entrimodel_binding_mismatchsetelah peralihan model memang wajar.
- Jaga riwayat percakapan tetap append-only: bekukan
systemdantoolssaat sesi dimulai dan pindahkan perubahan di tengah sesi ke pesanrole: "system"serta bloktool_addition/tool_removal, kirim pengingat per giliran sebagai pesan sistem berlingkup giliran yang tidak pernah Anda hapus, pangkas konteks di sisi server atau hapus blok thinking dari giliran mana pun yang Anda bawa melewati ringkasan sisi klien, dan referensikan file lintas giliran denganfile_id.
- Pilih
prefix_mismatch_behavioruntuk produksi ("error"secara default, atau"drop_block") dan pantau. Jika Anda memelihara alat yang dijalankan orang lain dengan kunci API mereka sendiri, uji dengan field tersebut diatur: akun baru diberlakukan secara default meskipun akun Anda tidak.
- Tinjau agent loop untuk perilaku satu-panggilan-alat-per-giliran dan tambahkan instruksi batching.
- Jika antarmuka Anda menampilkan teks progres di antara panggilan alat, atur
thinking.displayke"updates"(beta) atau"summarized"dan minta pembaruan dalam prompt.
- Jika Anda mengubah effort di antara permintaan, pindahkan perubahan tersebut ke pesan
role: "system"effort per pesan (beta) untuk mempertahankan hit cache.
- Tangani
stop_reason: "refusal"dan bacastop_details.category. Pertimbangkanfallbacks: "default"(beta).
- Evaluasi ulang
effortdengan sweep baru, dimulai darihigh, dan tetapkan ulang baseline biaya dan latensi pada beban kerja Anda sendiri. Tokenizer tidak berubah. Pembacaan cache prompt seharga seperempat dari tarif Haijun Fable 5.
Migrasi ke Haijun Fable 5.1 dari Haijun Opus 5
Haijun Fable 5.1 menggunakan pola Messages API dan penggunaan alat yang sama dengan Haijun Opus 5. Model ini mempertahankan jendela konteks 1M token secara default, 128k token output maksimum, minimum caching prompt 512 token, dan dukungan pesan sistem di tengah percakapan. Pembatasan prefill, pembatasan parameter sampling, dan default "omitted" untuk thinking.display juga tetap berlaku. Terapkan semua yang ada di Migrasi ke Haijun Fable 5.1 dari Haijun Fable 5, ditambah hal-hal berikut.
Perbarui nama model Anda
model = "haijun-opus-5" # Before
model = "haijun-fable-5-1" # After
# Atau, untuk model Project Glasswing dengan kemampuan yang sama:
model = "haijun-mythos-5-1" # AfterApa yang berubah
- Thinking tidak dapat lagi dinonaktifkan: Haijun Opus 5 menerima
thinking: {type: "disabled"}pada level efforthighatau lebih rendah. Padahaijun-fable-5-1danhaijun-mythos-5-1, adaptive thinking (pemikiran adaptif) selalu aktif, danthinking: {type: "disabled"}mengembalikan error 400 pada level effort apa pun. Hapus field tersebut, kendalikan pengeluaran token dengan level effort yang lebih rendah, dan tinjau kembalimax_tokensuntuk beban kerja yang berjalan dengan thinking dinonaktifkan.
- Pilihan alat paksa tidak didukung: Haijun Opus 5 menerima
tool_choiceanydantool.haijun-fable-5-1mengembalikan error 400. Lihat Perubahan yang merusak.
- Thinking yang dipertahankan lintas model: Haijun Fable 5.1 membaca blok thinking Haijun Opus 5: percakapan yang berpindah dari
haijun-opus-5kehaijun-fable-5-1mempertahankan penalarannya. Haijun Opus 5 tidak dapat membaca blok Haijun Fable 5.1. Blok Haijun Fable 5.1 juga berhenti valid ketika giliran sebelumnya berubah: jika kode Anda mengedit pesan sebelumnya, membangun ulangsystematautools, atau melakukan kompaksi di klien di antara permintaan, Haijun Opus 5 tidak keberatan, tetapihaijun-fable-5-1menolak atau membuang setiap blok thinking berikutnya. Jalankan pemeriksaan tiga langkah di bagian tersebut sebelum mengalihkan lalu lintas. Lihat Perubahan yang merusak.
- Teks di antara pemanggilan alat dikembalikan dalam blok thinking: Pada Haijun Opus 5, teks yang ditulis model di antara pemanggilan alat dikembalikan sebagai blok
text. Padahaijun-fable-5-1, seperti pada Haijun Fable 5, narasi tersebut dikembalikan sebagai blokthinkingpembaruan progres, satu sebelum setiap pemanggilan alat. Di bawahthinking.displaydefault"omitted", blok tersebut tidak membawa teks yang dapat dibaca. Jika antarmuka Anda merender narasi tersebut, seteldisplay: "updates"(beta) untuk menerima pembaruan progres sebagai teks sementara penalaran tetap tersembunyi, atau"summarized"untuk menerima keduanya. Kemudian render blokthinkingyang tidak kosong di antara bloktool_use. Lihat Pembaruan progres di antara pemanggilan alat.
- Pengklasifikasi keamanan dan perutean fallback: Haijun Fable 5.1 menjalankan pengklasifikasi keamanan yang mencakup kategori
stop_detailsyang sama dengan Haijun Fable 5, kumpulan yang lebih luas daripada pengklasifikasi khusus keamanan siber milik Haijun Opus 5. Harapkan nilaistop_details.categorydi luar"cyber", seperti"bio"dan"reasoning_extraction"; lihat tabel kategori penolakan untuk kumpulan lengkapnya. Untuk konfigurasifallbacksdan target yang diizinkan, lihat Gunakanfallbacks: "default"untuk penolakan.
- Harga: $10 USD per juta token input dan $50 USD per juta token output, dibandingkan dengan $5 USD dan $25 USD untuk Haijun Opus 5. Pembacaan cache prompt adalah $0,25 USD per juta token, setengah dari tarif Haijun Opus 5. Lihat Harga Haijun.
- Retensi data: Haijun Fable 5.1 dan Haijun Mythos 5.1 memerlukan retensi data 30 hari, tidak tersedia di bawah pengaturan zero data retention (ZDR) kecuali diizinkan secara tegas oleh Juglow, dan ditetapkan sebagai Covered Models. Haijun Opus 5 tersedia di bawah ZDR. Lihat Persyaratan retensi data khusus model.
Daftar periksa migrasi
- Jika organisasi Anda memiliki pengaturan "zero data retention" (retensi data nol), atau ZDR, pastikan kelayakan terlebih dahulu: model-model ini tidak tersedia di bawah ZDR kecuali diizinkan secara tegas oleh Juglow. Lihat Persyaratan retensi data khusus model.
- Perbarui nama model dari
haijun-opus-5menjadihaijun-fable-5-1(atauhaijun-mythos-5-1).
- Hapus konfigurasi
thinking: {type: "disabled"}apa pun karena konfigurasi tersebut mengembalikan error 400 padahaijun-fable-5-1. Kendalikan penggunaan token dengan level effort yang lebih rendah, dan tinjau kembalimax_tokens.
- Ganti
tool_choiceyang dipaksakan (anyatautool) denganautoditambah instruksi eksplisit (giliranuseratau pesan sistem di tengah percakapan) dan alat denganstrict: true, atau dengan output JSON.
- Jika antarmuka Anda menampilkan teks di antara pemanggilan alat, atur
display: "updates"(beta) atau"summarized"dan tampilkan blokthinkingyang tidak kosong.
- Terapkan item preserved-thinking, pengeditan riwayat, perilaku, effort, dan fallback dari daftar periksa Haijun Fable 5.
- Tetapkan ulang baseline biaya pada beban kerja Anda sendiri. Tokenizer tidak berubah. Harga per token berbeda.
Migrasi ke Haijun Fable 5.1 dari Haijun Opus 4.8 atau sebelumnya
Pertama, terapkan Bermigrasi ke Haijun Mythos 5 dan Haijun Fable 5 dari Haijun Opus 4.8 untuk perubahan tingkat API dari Haijun Opus 4.8. Bagian tersebut mencakup adaptive thinking, output thinking, penolakan, effort, batas minimum caching, harga, dan retensi data. Kemudian terapkan delta yang tersisa di Migrasi ke Haijun Fable 5.1 dari Haijun Fable 5. Jika Anda menggunakan Haijun Opus 4.7 atau yang lebih lama, mulailah dengan bagian yang sesuai di Migrasi ke Haijun Opus 5.5.
Perbarui nama model Anda
model = "haijun-opus-4-8" # Before
model = "haijun-fable-5-1" # After
# Atau, untuk model Project Glasswing dengan kemampuan yang sama:
model = "haijun-mythos-5-1" # AfterDaftar periksa migrasi
- Jika organisasi Anda memiliki pengaturan zero data retention (ZDR), konfirmasikan kelayakan terlebih dahulu: model-model ini tidak tersedia di bawah ZDR kecuali diizinkan secara tegas oleh Juglow. Haijun Opus 4.8 tersedia di bawah ZDR.
- Perbarui nama model dari
haijun-opus-4-8menjadihaijun-fable-5-1(atauhaijun-mythos-5-1).
- Hapus konfigurasi
thinking: {type: "disabled"}apa pun dan tinjau kembalimax_tokens. Permintaan tanpa fieldthinkingberjalan dengan adaptive thinking.
- Ganti
tool_choicepaksa (anyatautool) denganautoditambah instruksi eksplisit (giliranuseratau pesan sistem di tengah percakapan) dan alatstrict: true, atau dengan output JSON.
- Kirimkan kembali blok
thinkingtanpa perubahan dan perlakukan teksnya sebagai hanya-untuk-tampilan. Haijun Fable 5.1 membaca blok thinking Haijun Opus 4.8: percakapan yang berpindah kehaijun-fable-5-1mempertahankan penalaran sebelumnya. Haijun Opus 4.8 tidak dapat membaca blok Haijun Fable 5.1.
- Jika kode Anda membangun array
messagessendiri, periksa apakah kode tersebut mengedit giliran sebelumnya. Integrasi yang ditulis untuk Haijun Opus 4.8 dan sebelumnya sering memotong giliran lama, menghapus atau membangun ulang pesan sebelumnya, atau menyegarkan promptsystemsetiap permintaan, dan Haijun Opus 4.8 tidak pernah keberatan. Padahaijun-fable-5-1masing-masing hal tersebut membuat blok thinking berikutnya tidak valid.
- Tangani
stop_reason: "refusal", bacastop_details.category, dan pertimbangkanfallbacks: "default"(beta).
- Terapkan item thinking yang dipertahankan, pengeditan riwayat, perilaku, effort per pesan, dan pembaruan progres dari daftar periksa Haijun Fable 5.
- Evaluasi ulang
effort(mulai darihigh), tinjau prompt yang mendekati minimum caching 512 token, dan tetapkan ulang baseline biaya dan latensi. Harga per token berbeda.
Migrasi ke Haijun Mythos 5.1 dari Haijun Mythos 5
Haijun Mythos 5.1 adalah pasangan berakses terbatas dari Haijun Fable 5.1. Konfirmasikan akses organisasi Anda dengan tim akun Juglow Anda sebelum mengganti ID model.
Delta tingkat API sama dengan Migrasi ke Haijun Fable 5.1 dari Haijun Fable 5: pilihan alat paksa mengembalikan error 400, dan blok thinking dipertahankan hanya untuk model yang menghasilkannya atau model yang lebih baru (Haijun Mythos 5.1 membaca blok Haijun Mythos 5, bukan sebaliknya). Tidak seperti Haijun Fable 5.1, Haijun Mythos 5.1 tidak menjalankan pemeriksaan percakapan, sehingga mengedit giliran sebelumnya tidak membuat blok thinking tidak valid, meskipun tetap memulai ulang cache prompt.
Perbarui nama model Anda
model = "haijun-mythos-5" # Before
model = "haijun-mythos-5-1" # AfterDaftar periksa migrasi
- Perbarui nama model dari
haijun-mythos-5menjadihaijun-mythos-5-1.
- Ganti
tool_choicepaksa (anyatautool) denganautoditambah instruksi eksplisit (giliranuseratau pesan sistem di tengah percakapan) dan alatstrict: true, atau dengan output JSON.
- Tangani
stop_reason: "refusal"dan bacastop_details.categorysebelum konten respons. Lihat Penolakan dan fallback.
- Terus kirimkan kembali blok
thinkingtanpa perubahan pada setiap giliran, termasuk yang kosong.
- Jika kode Anda membangun array
messagessendiri, jaga riwayat percakapan agar hanya-tambah untuk menjaga cache prompt tetap hangat. Haijun Mythos 5.1 tidak menjalankan pemeriksaan percakapan, sehingga pengeditan tidak membuat blok thinking-nya tidak valid.
- Terapkan perubahan perilaku dan perubahan yang direkomendasikan dari bagian Haijun Fable 5, kecuali item pengeditan riwayat, yang tidak berlaku untuk Haijun Mythos 5.1.
- Evaluasi ulang
effortdengan sapuan baru dan tetapkan ulang baseline biaya dan latensi. Pembacaan cache prompt berbiaya seperempat dari tarif Haijun Mythos 5.