Haijun Platform Docs
EN

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 migrate untuk 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. Baik thinking: {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.
  • 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_error 400. 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_details yang sama dengan Haijun Fable 5. Permintaan yang ditolak mengembalikan stop_reason: "refusal" dengan stop_details.category, dan dapat beralih ke model lain dengan parameter fallbacks atau 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

python
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"  # After

Perubahan yang merusak kompatibilitas

  1. Tool choice paksa tidak didukung: Haijun Fable 5 menerima tool_choice auto, none, any, dan tool. Pada haijun-fable-5-1, {type: "any"} dan {type: "tool", name: "..."} mengembalikan invalid_request_error 400:
text
   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):

bash
     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
bash
     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
python
     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)
typescript
     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);
csharp
     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);
go
     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())
java

     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);
     }
php
     $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;
ruby
     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 message

Sesudah (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:

bash
     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
bash
     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
python
     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)
typescript
     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);
csharp
     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);
go
     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())
java

     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);
     }
php
     $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;
ruby
     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 message

Lihat 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:

bash
     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
bash
     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
python
     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)
typescript
     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);
csharp
     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);
go
     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())
java

     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);
     }
php
     $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;
ruby
     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 message

Pertahankan 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.

  1. Blok thinking hanya dipertahankan untuk model yang menghasilkannya, atau model yang lebih baru: Setiap blok thinking mencatat 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 ke haijun-fable-5-1 dari 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.

  1. Mengedit giliran sebelumnya membatalkan blok thinking: Setiap blok thinking dari Haijun Fable 5.1 hanya valid terhadap prompt system, 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 array messages sendiri, 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:
text
   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:

bash
     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?"
           }
         ]
       }'
bash
     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
python
     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 [])}")
typescript
     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}`);
csharp
     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}");
go
     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))
java
     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));
     }
php
     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;
ruby
     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_result dan dihapus pada permintaan berikutnya. Sebagai gantinya, kirim pengingat tersebut sebagai pesan sistem berlingkup giliran dan biarkan tetap ada dalam riwayat.
  • Membangun ulang prompt system tingkat atas atau array tools di 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 blok tool_addition dan tool_removal. Alat yang tidak dideklarasikan dalam tools di awal dapat didefinisikan di dalam blok tool_addition (beta header inline-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 luar system, tools, dan messages, serta menambah atau memindahkan penanda cache_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:

  1. 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, array tools, dan prefiks bersama dari messages. Semuanya harus identik byte demi byte hingga giliran yang baru ditambahkan. Satu pengecualian yang wajar adalah permintaan yang menyisipkan blok compaction bertanda tangan dari compaction sesuai permintaan: blok tersebut menggantikan pesan-pesan yang diringkasnya di bagian depan messages, dan semua yang ada setelahnya harus tetap cocok.
  2. Jalankan sesi multi-giliran normal terhadap haijun-fable-5-1 dengan beta header thinking-binding-controls-2026-08-01 dan prefix_mismatch_behavior: "drop_block", lalu catat input_transformations pada setiap respons. Array kosong pada setiap giliran berarti riwayat masih utuh. Entri dengan reason: "prefix_binding_mismatch" berarti ada sesuatu sebelum blok di path yang berubah sejak permintaan sebelumnya. Entri dengan reason: "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.
  3. 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 entri input_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

  1. 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 blok tool_result, dan biarkan salinan sebelumnya dalam riwayat pada permintaan berikutnya. Lihat Batch pemanggilan alat independen dalam agent loop.
  1. 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.display ke "updates" (beta) atau "summarized" dan minta secara eksplisit melalui prompt. Lihat Pembaruan progres di antara pemanggilan alat dan Minta pembaruan progres untuk pengguna.
  1. 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:

  1. Ubah effort di tengah percakapan (beta): Pada Haijun Fable 5, output_config.effort berada di tingkat permintaan, dan mengubahnya di antara permintaan membuang prefiks yang di-cache dari giliran sebelumnya. Pada haijun-fable-5-1, pesan role: "system" yang hanya membawa output_config menaikkan effort untuk langkah yang sulit atau menurunkannya untuk langkah rutin tanpa membatalkan cache prompt:
bash
     # 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."}
         ]
       }'
bash
     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
python
     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)
typescript
     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);
       }
     }
csharp
     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);
         }
     }
go
     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)
     	}
     }
java
     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()));
     }
php
     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;
         }
     }
ruby
     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
     end

Nilai 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.

  1. Ubah instruksi dan alat dengan pesan sistem di tengah percakapan: Untuk mengubah instruksi atau alat di tengah sesi, tambahkan pesan role: "system", dengan blok tool_addition dan tool_removal untuk perubahan alat (beta header inline-tools-2026-09-15 di Haijun API). Blok tool_addition dapat menyebutkan alat yang dideklarasikan di tools saat sesi dimulai atau membawa definisi lengkap alat tersebut, sehingga alat yang belum diketahui saat sesi dimulai tidak perlu ada di tools. Ini mempertahankan hit cache prompt pada giliran sebelumnya dan menjaga riwayat percakapan tetap append-only. Header lama mid-conversation-tool-changes-2026-07-01 masih berfungsi untuk perubahan yang menyebutkan alat berdasarkan referensi, di Haijun API, Amazon Bedrock, dan Google Cloud. Pesan yang sama menggantikan tool_choice yang 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 pesan role: "system" terpisah yang hanya berisi teks dengan clear_at: "next_user_message" (pesan sistem berlingkup giliran, beta header mid-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 blok tool_addition atau tool_removal tidak dapat dibuat berlingkup giliran.
  1. Gunakan fallbacks: "default" untuk penolakan: Tetap tangani stop_reason: "refusal" dan baca stop_details.category sebelum konten respons. Untuk menjalankan ulang permintaan yang ditolak pada model lain secara otomatis, atur fallbacks: "default" (beta, header server-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). Daftar fallbacks eksplisit 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.
  1. Mulai dari effort high dan lakukan sweep: Default parameter effort adalah high, dan kelima level didukung. Pertahankan panduan Haijun Fable 5: high untuk sebagian besar pekerjaan, dan medium sebagai kontrol biaya yang layak diuji. Peningkatan Haijun Fable 5.1 dibandingkan Haijun Fable 5 paling besar pada xhigh dan max, 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.
  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 instructions pada 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 header compact-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 thinking dan redacted_thinking dari giliran tersebut (teks dan pemanggilan alat boleh tetap ada), atau atur prefix_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_transformations pada 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-5 ke haijun-fable-5-1 (atau haijun-mythos-5 ke haijun-mythos-5-1).
  • Ganti tool_choice paksa ({type: "any"} atau {type: "tool", ...}). Ini mengembalikan error 400. Gunakan {type: "auto"} ditambah instruksi eksplisit dan alat strict: true, atau output JSON. Letakkan instruksi di giliran user, atau dalam pesan role: "system" di tengah percakapan ketika aplikasi Anda memerlukan panggilan tersebut.
  • Tetap kirim kembali blok thinking tanpa 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 messages sendiri, periksa apakah kode tersebut mengedit giliran sebelumnya: jalankan sesi dengan beta header thinking-binding-controls-2026-08-01 dan prefix_mismatch_behavior: "drop_block", catat input_transformations, dan perbaiki setiap prefix_binding_mismatch. Entri model_binding_mismatch setelah peralihan model memang wajar.
  • Jaga riwayat percakapan tetap append-only: bekukan system dan tools saat sesi dimulai dan pindahkan perubahan di tengah sesi ke pesan role: "system" serta blok tool_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 dengan file_id.
  • Pilih prefix_mismatch_behavior untuk 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.display ke "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 baca stop_details.category. Pertimbangkan fallbacks: "default" (beta).
  • Evaluasi ulang effort dengan sweep baru, dimulai dari high, 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

python
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"  # After

Apa yang berubah

  1. Thinking tidak dapat lagi dinonaktifkan: Haijun Opus 5 menerima thinking: {type: "disabled"} pada level effort high atau lebih rendah. Pada haijun-fable-5-1 dan haijun-mythos-5-1, adaptive thinking (pemikiran adaptif) selalu aktif, dan thinking: {type: "disabled"} mengembalikan error 400 pada level effort apa pun. Hapus field tersebut, kendalikan pengeluaran token dengan level effort yang lebih rendah, dan tinjau kembali max_tokens untuk beban kerja yang berjalan dengan thinking dinonaktifkan.
  1. Pilihan alat paksa tidak didukung: Haijun Opus 5 menerima tool_choice any dan tool. haijun-fable-5-1 mengembalikan error 400. Lihat Perubahan yang merusak.
  1. Thinking yang dipertahankan lintas model: Haijun Fable 5.1 membaca blok thinking Haijun Opus 5: percakapan yang berpindah dari haijun-opus-5 ke haijun-fable-5-1 mempertahankan 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 ulang system atau tools, atau melakukan kompaksi di klien di antara permintaan, Haijun Opus 5 tidak keberatan, tetapi haijun-fable-5-1 menolak atau membuang setiap blok thinking berikutnya. Jalankan pemeriksaan tiga langkah di bagian tersebut sebelum mengalihkan lalu lintas. Lihat Perubahan yang merusak.
  1. 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. Pada haijun-fable-5-1, seperti pada Haijun Fable 5, narasi tersebut dikembalikan sebagai blok thinking pembaruan progres, satu sebelum setiap pemanggilan alat. Di bawah thinking.display default "omitted", blok tersebut tidak membawa teks yang dapat dibaca. Jika antarmuka Anda merender narasi tersebut, setel display: "updates" (beta) untuk menerima pembaruan progres sebagai teks sementara penalaran tetap tersembunyi, atau "summarized" untuk menerima keduanya. Kemudian render blok thinking yang tidak kosong di antara blok tool_use. Lihat Pembaruan progres di antara pemanggilan alat.
  1. Pengklasifikasi keamanan dan perutean fallback: Haijun Fable 5.1 menjalankan pengklasifikasi keamanan yang mencakup kategori stop_details yang sama dengan Haijun Fable 5, kumpulan yang lebih luas daripada pengklasifikasi khusus keamanan siber milik Haijun Opus 5. Harapkan nilai stop_details.category di luar "cyber", seperti "bio" dan "reasoning_extraction"; lihat tabel kategori penolakan untuk kumpulan lengkapnya. Untuk konfigurasi fallbacks dan target yang diizinkan, lihat Gunakan fallbacks: "default" untuk penolakan.
  1. 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.
  1. 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-5 menjadi haijun-fable-5-1 (atau haijun-mythos-5-1).
  • Hapus konfigurasi thinking: {type: "disabled"} apa pun karena konfigurasi tersebut mengembalikan error 400 pada haijun-fable-5-1. Kendalikan penggunaan token dengan level effort yang lebih rendah, dan tinjau kembali max_tokens.
  • Ganti tool_choice yang dipaksakan (any atau tool) dengan auto ditambah instruksi eksplisit (giliran user atau pesan sistem di tengah percakapan) dan alat dengan strict: true, atau dengan output JSON.
  • Jika antarmuka Anda menampilkan teks di antara pemanggilan alat, atur display: "updates" (beta) atau "summarized" dan tampilkan blok thinking yang tidak kosong.
  • 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

python
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"  # After

Daftar 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-8 menjadi haijun-fable-5-1 (atau haijun-mythos-5-1).
  • Hapus konfigurasi thinking: {type: "disabled"} apa pun dan tinjau kembali max_tokens. Permintaan tanpa field thinking berjalan dengan adaptive thinking.
  • Ganti tool_choice paksa (any atau tool) dengan auto ditambah instruksi eksplisit (giliran user atau pesan sistem di tengah percakapan) dan alat strict: true, atau dengan output JSON.
  • Kirimkan kembali blok thinking tanpa perubahan dan perlakukan teksnya sebagai hanya-untuk-tampilan. Haijun Fable 5.1 membaca blok thinking Haijun Opus 4.8: percakapan yang berpindah ke haijun-fable-5-1 mempertahankan penalaran sebelumnya. Haijun Opus 4.8 tidak dapat membaca blok Haijun Fable 5.1.
  • Jika kode Anda membangun array messages sendiri, 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 prompt system setiap permintaan, dan Haijun Opus 4.8 tidak pernah keberatan. Pada haijun-fable-5-1 masing-masing hal tersebut membuat blok thinking berikutnya tidak valid.
  • Tangani stop_reason: "refusal", baca stop_details.category, dan pertimbangkan fallbacks: "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 dari high), 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

python
model = "haijun-mythos-5"  # Before
model = "haijun-mythos-5-1"  # After

Daftar periksa migrasi

  • Perbarui nama model dari haijun-mythos-5 menjadi haijun-mythos-5-1.
  • Ganti tool_choice paksa (any atau tool) dengan auto ditambah instruksi eksplisit (giliran user atau pesan sistem di tengah percakapan) dan alat strict: true, atau dengan output JSON.
  • Tangani stop_reason: "refusal" dan baca stop_details.category sebelum konten respons. Lihat Penolakan dan fallback.
  • Terus kirimkan kembali blok thinking tanpa perubahan pada setiap giliran, termasuk yang kosong.
  • Jika kode Anda membangun array messages sendiri, 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 effort dengan sapuan baru dan tetapkan ulang baseline biaya dan latensi. Pembacaan cache prompt berbiaya seperempat dari tarif Haijun Mythos 5.
On this page
Migrasi ke Haijun Fable 5.1 dari Haijun Fable 5Perbarui nama model AndaPerubahan yang merusak kompatibilitasPerubahan perilakuPerubahan yang direkomendasikanDaftar periksa migrasiMigrasi ke Haijun Fable 5.1 dari Haijun Opus 5Perbarui nama model AndaApa yang berubahDaftar periksa migrasiMigrasi ke Haijun Fable 5.1 dari Haijun Opus 4.8 atau sebelumnyaPerbarui nama model AndaDaftar periksa migrasiMigrasi ke Haijun Mythos 5.1 dari Haijun Mythos 5Perbarui nama model AndaDaftar periksa migrasi