SuiteScript
NetSuite 2025.2
2026-07-23

N/llm generateText Now Supports Tool Calling, Structured Output, and Safety Modes

The N/llm module's generateText method gains tool-calling support in 2025.2 (options.tools, options.toolResults), adding to structured JSON output (options.responseFormat), document RAG (options.documents), and safety modes introduced in 2025.1. The method costs 100 governance units per call and runs server-side only.

Affects:SuiteScript 2.1N/llmServer-Side Scripts

The llm.generateText(options) method — aliased as llm.chat(options) — is the primary entry point for calling LLMs from SuiteScript 2.1 via the N/llm module. Originally shipped in 2024.1, it has been progressively expanded. Here is a consolidated breakdown of the API surface through 2025.2, with emphasis on the newest capabilities.

What changed in 2025.2: Tool Calling

Two new parameters enable agentic tool-use patterns:

  • options.tools (llm.Tool[]) — Declares tools (functions) the LLM may request during generation. When the model decides it needs external data, the response object's Response.toolCalls property contains the requested invocations.
  • options.toolResults (llm.ToolResult[]) — Feeds completed tool results back into generateText so the LLM can produce a follow-up response incorporating those results. When toolResults is specified, any value in options.prompt is ignored.

This creates a two-call loop: call generateText with tools → inspect response.toolCalls → execute the requested tools in your script → call generateText again with toolResults. Each call costs 100 governance units, so a single tool-augmented exchange burns at least 200 units.

What changed in 2025.1

  • options.documents (llm.Document[]) — Supplies documents for retrieval-augmented generation (RAG). Cohere models only. Create documents via llm.createDocument(options). Document IDs must be unique or you get DOCUMENT_IDS_MUST_BE_UNIQUE.
  • options.responseFormat (JSON Schema object) — Forces the LLM to return structured JSON matching your schema. Parse the result with JSON.parse(response.text). Cohere models only. Cannot be combined with options.documents, options.tools, or options.toolResults (throws MUTUALLY_EXCLUSIVE_ARGUMENTS).
  • options.safetyMode — Controls content filtering via the llm.SafetyMode enum. Defaults to llm.SafetyMode.STRICT. Even with llm.SafetyMode.OFF, some content filtering is still enforced and can throw INAPPROPRIATE_CONTENT_DETECTED.

Existing parameters (2024.1–2024.2)

  • options.prompt (string) — Required unless toolResults is provided.
  • options.chatHistory (llm.ChatMessage[]) — Prior conversation turns for multi-turn chat.
  • options.preamble (string) — System-level instruction/context. Not all models accept it (MODEL_1_DOES_NOT_ACCEPT_PREAMBLE).
  • options.modelFamily (string, since 2024.2) — Select the LLM via llm.ModelFamily enum. Defaults to Cohere Command A (cohere.command-a-03-2025).
  • options.modelParametersmaxTokens, temperature, topK, topP, frequencyPenalty, presencePenalty. Note: for COHERE_COMMAND, you cannot set both frequencyPenalty and presencePenalty above zero simultaneously.
  • options.ociConfig — Needed only for unlimited-usage mode via your own OCI Generative AI service account. Accepts userId, tenancyId, compartmentId, fingerprint, privateKey. The fingerprint and privateKey values must be NetSuite API secrets (not raw strings) or you get ONLY_API_SECRET_IS_ACCEPTED. OCI config can also be set globally on the AI Preferences > SuiteScript subtab; per-call values override the global config.
  • options.timeout — Defaults to 30,000 ms.

Runtime constraints

  • Governance: 100 units per call.
  • Script type: Server-side scripts only.
  • Parallelism: Maximum 5 concurrent LLM requests per script execution (MAXIMUM_PARALLEL_REQUESTS_LIMIT_EXCEEDED).

Key error codes to handle

  • SSS_MISSING_REQD_ARGUMENT — No prompt and no toolResults.
  • MUTUALLY_EXCLUSIVE_ARGUMENTSresponseFormat combined with documents, tools, or toolResults; or both penalty parameters set for Cohere Command.
  • INAPPROPRIATE_CONTENT_DETECTED — Safety filter triggered (even with safety mode off).
  • INVALID_*_VALUE family — Model parameter out of range; check Model Parameter Values by LLM in the NetSuite help.

What to do

  1. If you are already using N/llm — Review the new options.tools and options.toolResults parameters. Tool calling lets your SuiteScript act as an agent orchestrator, but remember each round-trip is 100 governance units. Plan your governance budget accordingly, especially in scheduled or map/reduce scripts.
  2. If you want structured output — Use options.responseFormat with a JSON schema instead of hoping the prompt returns parseable JSON. This is Cohere-only and cannot be used alongside tools, toolResults, or documents.
  3. If you use unlimited-usage (BYO OCI) mode — Prefer setting OCI config on the AI Preferences > SuiteScript subtab for account-wide defaults. Use per-call ociConfig only when you need to override for a specific script. Ensure fingerprint and privateKey are stored as NetSuite Secrets (Setup > Company > API Secrets), not hardcoded strings.
  4. Governance planning — A tool-calling exchange is at minimum 2 × 100 = 200 units. With a 5-request parallelism cap, batch designs that fan out many LLM calls need serialization or chunking. Factor this into your script-type selection (Scheduled, Map/Reduce, RESTlet).
  5. Default model awareness — The default modelFamily is now Cohere Command A (cohere.command-a-03-2025). If your code relied on a previous default, explicitly set options.modelFamily to maintain consistent behavior.