This guide describes enterprise Hook configuration, HTTP invocation conventions, and event requests and responses for QwenWork.
This guide describes enterprise Hook configuration, HTTP invocation conventions, and event requests and responses for QwenWork. The desktop client invokes enterprise-provided HTTP services.
The current QwenWork enterprise flagship edition (qwenwork_premium) supports these 12 events:
In the enterprise console, go to Security → Hooks, select an event, and enter its JSON configuration array. Each array item is a Hook group: matcher determines when it matches, and hooks lists the services to invoke on a match.
The following configuration invokes a check service before the Bash tool executes. Configure it for the PreToolUse event:
Hook group fields:
matcher matches the tool name for PreToolUse and PostToolUse, source for SessionStart, notification_type for Notification, and trigger (manual or auto) for PreCompact and PostCompact. UserPromptSubmit and Stop do not require this field.
Omit matcher for PreUserPromptSubmit, ConnectorAdded, ExpertSuiteAdded, and SkillAdded. Omission, an empty string, or "*" matches all; other values are regular expressions matched against the event name, not the prompt, file name, or connector name. Filter content by examining the request body on your server.
matcher matching rules
HTTP Hook fields:
When multiple Hooks match an event, PreUserPromptSubmit, ConnectorAdded, ExpertSuiteAdded, and SkillAdded execute them sequentially in configuration order. A valid block stops execution immediately; a later allow cannot override it. URLs are not deduplicated. Other events execute Hooks in parallel by default and deduplicate identical URLs; do not rely on array order.
Additional handling for PreUserPromptSubmit, ConnectorAdded, ExpertSuiteAdded, and SkillAdded:
These 4 events do not follow HTTP redirects. To block, return HTTP 2xx with a valid block response. HTTP 403, HTTP 500, or a block missing required fields is treated as an error and skipped, without blocking.
The client fills request fields automatically; they are not customer configuration fields. SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, Stop, Notification, PreCompact, and PostCompact include the following common information:
PreCompact and PostCompact include only the basic fields in the example above and their event-specific fields, excluding permission_mode, agent_id, agent_type, and model.
PreUserPromptSubmit, ConnectorAdded, ExpertSuiteAdded, and SkillAdded use these common fields:
These 4 events do not include engine fields such as event, cwd, or transcript_path. Only PreUserPromptSubmit additionally includes session_id and turn_id. User, request, session, and version values in the examples are illustrative.
If hookSpecificOutput is present, it must contain hookEventName, set to the current event name. Top-level decision does not accept ask; use permissionDecision for tool confirmation.
continue: false controls execution for UserPromptSubmit, PreToolUse, PostToolUse, and Stop. SessionStart supplements context; Notification does not control the flow through responses. Do not use async: true to express asynchronous enterprise HTTP callback processing.
PreUserPromptSubmit, ConnectorAdded, ExpertSuiteAdded, and SkillAdded accept only the strict JSON responses listed for each event, without the common response fields above. Unknown fields, incorrect types, invalid combinations, plain text, and {} are invalid responses. See the corresponding events for PreCompact and PostCompact responses.
The request examples below show event names and event-specific fields. Actual requests also include the corresponding common information from “Common request fields”. Handle HTTP failures according to “HTTP invocation conventions”.
Triggered when a session starts or resumes, to provide context such as business background and project constraints.
Request body:
Response body:
Plain text can also be returned as context. Return {} if there is no additional content. This event does not set operating-system environment variables.
Triggered for each user-submitted text input, before it is saved to the official chat transcript and reaches the Agent. It replaces or blocks the entire input for this turn. The existing UserPromptSubmit receives the processed text afterward and can only block or supplement context using its original protocol; it cannot replace the entire input.
Request body:
Response body:
Allow and preserve the original text:
After replacement, the official chat transcript, displayed user message, subsequent session history, and model input use the replaced text with an enterprise-processing marker. Blocking does not add an official user message and leaves the input editable. This event handles text only; it does not review or replace attachments, system instructions, tool arguments, or tool results.
Multiple Hooks process the same turn sequentially. One Hook's replacement becomes the next Hook's prompt; a later service error does not restore the original text. The last valid allow response's isFirstTurn determines the displayed turn marker.
Triggered after prompt submission but before model processing, to inspect input or supplement context. matcher does not filter prompt content.
Request body:
To reject this input, return:
Return {} for no additional behavior. Plain-text context is also supported. Do not return prompt to replace user input.
Triggered before actual tool execution to validate or change arguments, allow or deny the call, or request user confirmation. matcher matches tool_name (such as Bash, Write, Edit, Read, Glob, Grep, or MCP tool names such as mcp__server__tool).
Request body:
Response example: adjust the command arguments for a read-only check and request user confirmation.
Return {} when there is no permission decision; do not use allow to mean “no opinion”. Decisions from multiple Hooks are aggregated as deny > ask > allow; allowed calls are still subject to tool permission rules.
deny rejects only this tool call. Use continue: false to stop the current execution.
Triggered after successful tool execution to inspect results, supplement context, or replace output. matcher matches tool_name.
Request body:
Block the tool result:
Replacement fields should contain nonempty strings. If both are present, updatedToolOutput takes precedence. Multiple Hooks should not modify the same input or output simultaneously.
The tool has already executed when this event occurs. Rejecting or replacing its result does not undo file changes, command execution, or external calls. Use PreToolUse to prevent the operation.
Triggered when the Agent is about to finish the current turn, to check delivery conditions. block means “do not finish yet; continue working”.
Request body:
To require additional work, return:
continue: false stops execution; it does not request further work. Check stop_hook_active and define a termination condition on your server. For example, return {} after requiring further work once to avoid repeated triggering.
Triggered for notifications such as permission confirmation and MCP elicitation. matcher matches notification_type, not the tool name.
Request body:
notification_type values:
Return {} after receipt. This event's response does not approve, deny, or change the original operation. Some paths still wait for the HTTP response, so respond quickly. A particular client may not emit every notification type, and idle_prompt is not guaranteed for every completed task.
Triggered before actual manual or automatic context compaction, not on every conversation turn. matcher matches trigger.
Request body:
Response body:
Do not intervene in this compaction:
Preventing compaction does not terminate the session or guarantee that model requests can continue after the context limit is exceeded. Verify compaction control against the delivered version during integration testing.
Triggered after successful context compaction to receive its summary. Failed or prevented compaction does not trigger a success notification. matcher matches trigger.
Request body:
Response body:
Reviews a connector's pending configuration, covering controlled creation, import, marketplace installation, enabling, and configuration updates. After a valid block, the client does not register, enable, or apply the update; previously effective configuration is not undone.
Request body:
The client processes explicit credential fields such as tokens, passwords, Cookie, and Authorization, as well as URL credentials, sensitive query parameters, and explicit command arguments. Redaction is not a general-purpose secret detector; do not hide credentials in unrecognizable custom fields, text, or command fragments.
Response body:
Allow:
content_digest is computed from the actual configuration before redaction and cannot be recomputed from the received redacted config. Triggered when adding, enabling, or changing connectors through controlled client entries; directly editing configuration files on disk is not guaranteed to trigger it.
Reviews the complete file snapshot before plugin installation, including the manifest, skills, scripts, and other resources. Reading the review content does not execute package scripts.
Request body:
Response body:
Allow:
Triggered through controlled installation entries in the marketplace, local import, or conversation. The same complete file snapshot is installed after review. A snapshot is limited to 20 MiB of raw content and 5000 files. Symbolic links, special files, exceeded limits, or read failures are local validation failures and stop installation. Directly editing directories on disk is not guaranteed to trigger it.
Reviews the complete file snapshot before skill installation, including SKILL.md, scripts, references, and other resources, not just the skill description.
Request body:
Response body:
Allow:
Triggered through controlled installation entries in the marketplace, local import, or conversation. The same complete file snapshot is installed after review. A snapshot is limited to 20 MiB of raw content and 5000 files. Symbolic links, special files, exceeded limits, or read failures are local validation failures and stop installation. Directly editing directories on disk is not guaranteed to trigger it.
Currently supported Hooks events
The current QwenWork enterprise flagship edition (qwenwork_premium) supports these 12 events:
| Event | When triggered | Typical uses | Can block the operation |
|---|---|---|---|
| SessionStart | When a session starts, resumes, or restarts after clearing or compaction | Session recording and injecting enterprise rules | Blocking is not recommended |
| UserPromptSubmit | After the user submits content, before it reaches the Agent | Sensitive information and prompt compliance checks | Yes |
| PreToolUse | Before the Agent invokes a tool | Command and file-operation controls, permission approval | Yes |
| PostToolUse | After tool execution completes | Operation auditing and result checks | Execution has already occurred and cannot be undone |
| Stop | When the Agent is about to finish its current response | Completeness checks and requiring further work | Can prevent the Agent from stopping |
| Notification | When the Agent emits a notification | Notification forwarding and security auditing | Blocking is not recommended |
| PreUserPromptSubmit | Before each user input is saved and sent to the Agent, including the first and subsequent turns | Prompt replacement and input compliance checks | Yes |
| PreCompact | Before manual or automatic context compaction | Pre-compaction checks | Can prevent this compaction |
| PostCompact | After successful context compaction | Recording the compaction summary | Compaction has already occurred and cannot be undone |
| ConnectorAdded | Before adding, enabling, or updating a connector takes effect | Connector configuration security approval | Yes |
| ExpertSuiteAdded | Before a plugin installation takes effect | Security approval of the plugin's complete files | Yes |
| SkillAdded | Before a skill installation takes effect | Security approval of the skill's complete files | Yes |
Hook configuration
Hook configuration format
In the enterprise console, go to Security → Hooks, select an event, and enter its JSON configuration array. Each array item is a Hook group: matcher determines when it matches, and hooks lists the services to invoke on a match.
The following configuration invokes a check service before the Bash tool executes. Configure it for the PreToolUse event:
Replace the URL and credentials with actual values. Omit headers if authentication is unnecessary. An empty configuration array [] disables enterprise Hook calls for this event.
All events use this Hook group array structure. Select the corresponding event in the console; do not wrap the array in an additional event-name or hooks object.
Fields
Hook group fields:
matcher matches the tool name for PreToolUse and PostToolUse, source for SessionStart, notification_type for Notification, and trigger (manual or auto) for PreCompact and PostCompact. UserPromptSubmit and Stop do not require this field.
| Field | Type | Required | Description |
|---|---|---|---|
| matcher | string | No | Case-sensitive JavaScript regular expression; omitting it matches all |
| hooks | array | Yes | List of HTTP Hooks containing at least 1 item |
| Pattern | Meaning | Example |
|---|---|---|
| Omitted | Match all | Every tool triggers the Hook |
| Exact value | Exact match | "Bash" matches only the Bash tool |
| Separated by ` | ` | Match multiple values |
| Regular expression | Regex match | "mcp__.*" matches all MCP tools |
| Field | Type | Required | Description |
|---|---|---|---|
| type | string | Yes | Must be http. The client rejects other types and does not execute them |
| url | string | Yes | Full HTTP or HTTPS URL that receives the event |
| timeout | number | No | Timeout in seconds, greater than 0. Defaults to 10 seconds for PreUserPromptSubmit, ConnectorAdded, ExpertSuiteAdded, and SkillAdded; 600 seconds for other events. Explicit configuration is recommended. |
| headers | object<string, string> | No | Custom headers with string keys and values. An explicit headers.Accept overrides the default. |
HTTP invocation conventions
- **Method:**POST, with the current event's JSON object as the body.
- **Headers:**Content-Type: application/json and Accept: application/json by default, plus configured headers.
- Timeout: The call ends after timeout; automatic retries are not currently performed.
| HTTP status | Response body | Client behavior |
|---|---|---|
| 2xx | Empty | Leaves the original flow unchanged |
| 2xx | Valid JSON object | Processes the response fields supported by the current event |
| 2xx | Plain text | SessionStart and UserPromptSubmit use the text as context; PreToolUse interprets it as allow, which is not recommended |
| 2xx | Invalid JSON syntax or field validation failure | PreToolUse rejects the tool call; other events log the error and continue |
| Non-2xx | Any | Logs the invocation error and continues the original flow |
| Connection failure or timeout | — | Logs the invocation error and continues the original flow |
| Result | Handling |
|---|---|
| HTTP 2xx + valid allow | Continues to subsequent Hooks; proceeds with the original operation if none blocks it. |
| HTTP 2xx + valid block | Stops the operation immediately and skips remaining Hooks. Skills, plugins, and connectors display reason as plain text without executing HTML. |
| Service unreachable, connection failure, timeout, or non-2xx HTTP (including 4xx and 5xx) | Logs the error, skips this Hook, and continues subsequent Hooks; proceeds with the original operation unless a valid block is received. |
| Empty response, plain text, invalid JSON, unknown fields, or field validation failure | Logs the error, skips this Hook, and continues the original flow. This is not a successful approval. |
| User cancellation, identity not ready or changed during the request, local URL safety validation failure, or file validation failure | Stops the operation. These are not service outages and do not permit proceeding on error. |
Hook input and output
Common request fields
The client fills request fields automatically; they are not customer configuration fields. SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, Stop, Notification, PreCompact, and PostCompact include the following common information:
| Field | Type | Description |
|---|---|---|
| event | string | HTTP event name, identical to hook_event_name |
| hook_event_name | string | Current event name, usable for server-side dispatch |
| session_id | string | Current session ID |
| transcript_path | string | Local path to the client's session transcript |
| cwd | string | Client's current working directory |
| permission_mode | string, may be omitted | Current permission mode |
| agent_id | string, may be omitted | Agent ID |
| agent_type | string, may be omitted | Agent type |
| model | string, may be omitted | Model identifier, currently available in SessionStart |
| Request field | Type | Description |
|---|---|---|
| hook_event_name | string | Current event name, usable for server-side dispatch. |
| request_id | string | Stable identifier derived from user identity, the logical operation, and its content. Use it to correlate requests; it is neither a never-repeating global sequence number nor a promise of automatic client retries. |
| user_id | string | ID of the current logged-in user whose identity has been reconciled. |
| app_version | string | Client version. |
Common response fields
- Plain text: Only for supplemental context in SessionStart and UserPromptSubmit.
- JSON object: Returns control fields such as decision, reason, and hookSpecificOutput.
| Field | Type | Description |
|---|---|---|
| continue | boolean | false requests stopping the current execution; omission does not actively stop it |
| stopReason | string | Reason for stopping, used with continue: false |
| decision | string | Business decision; block blocks, with event-specific meaning described below |
| reason | string | Reason for the business decision |
| hookSpecificOutput | object | Event-specific response fields |
Hook events
The request examples below show event names and event-specific fields. Actual requests also include the corresponding common information from “Common request fields”. Handle HTTP failures according to “HTTP invocation conventions”.
SessionStart
Triggered when a session starts or resumes, to provide context such as business background and project constraints.
Request body:
| Field | Type | Description |
|---|---|---|
| source | string | Session source: startup (new), resume (resumed), clear (started after clearing), compact (resumed after compaction), etc. |
| Event-specific response field | Type | Description |
|---|---|---|
| additionalContext | string | Session context added for the model |
PreUserPromptSubmit
Triggered for each user-submitted text input, before it is saved to the official chat transcript and reaches the Agent. It replaces or blocks the entire input for this turn. The existing UserPromptSubmit receives the processed text afterward and can only block or supplement context using its original protocol; it cannot replace the entire input.
Request body:
| Event field | Type | Description |
|---|---|---|
| session_id | string | Client session identifier, which may be preallocated for the first turn. |
| turn_id | string | Client identifier for this logical submission, distinct from the native engine's internal Turn ID. |
| isFirstTurn | boolean | Whether the request is the actual first user input. Resubmitting a blocked first turn remains true; restarting or reopening the session does not reset it. |
| prompt | string | Text to submit for this turn. |
Allow and replace the entire text for this turn:
Block this submission:
| Response field | Type | Constraints |
|---|---|---|
| decision | string | Required; only allow or block. |
| isFirstTurn | boolean | Required in both response types and returned by the server. Controls the first/subsequent-turn replacement marker and block notice. Normally echoes the request value; the client does not require equality. |
| updated_prompt | string | Allowed only with allow; must be a nonblank string. Omission preserves the current text. |
| reason | string | Allowed only with block; required and must be nonblank. |
UserPromptSubmit
Triggered after prompt submission but before model processing, to inspect input or supplement context. matcher does not filter prompt content.
Request body:
| Field | Type | Description |
|---|---|---|
| prompt | string | User prompt for this submission |
To supplement context, return:
| Response field | Type | Description |
|---|---|---|
| decision | string | block prevents this prompt from reaching the model; omit if there is no decision |
| reason | string | Reason for rejection; the UI does not guarantee verbatim display |
| hookSpecificOutput.additionalContext | string | Context added to this request |
PreToolUse
Triggered before actual tool execution to validate or change arguments, allow or deny the call, or request user confirmation. matcher matches tool_name (such as Bash, Write, Edit, Read, Glob, Grep, or MCP tool names such as mcp__server__tool).
Request body:
| Field | Type | Description |
|---|---|---|
| tool_use_id | string | ID of this tool call |
| tool_name | string | Tool name |
| tool_input | object | Tool input arguments |
| mcp_context | object, optional | MCP service information: server_name, tool_name, and optionally url, command, args, cwd, and tcp |
| original_request_name | string, optional | Request name before tool-name resolution or alias conversion |
| Event-specific response field | Type | Description |
|---|---|---|
| permissionDecision | string | allow: explicitly allow;deny: deny;ask: request confirmation; |
| permissionDecisionReason | string | Reason for the permission decision |
| updatedInput | object | Replaces the entire tool argument object rather than merging selected fields; arguments are revalidated after replacement |
| additionalContext | string | Additional explanation for the model |
PostToolUse
Triggered after successful tool execution to inspect results, supplement context, or replace output. matcher matches tool_name.
Request body:
Tool fields are the same as for PreToolUse, plus:
| Field | Type | Description |
|---|---|---|
| tool_response | object | Tool execution result, whose structure varies by tool; the example is not a fixed response schema |
Supplement or replace the tool result:
| Response field | Type | Description |
|---|---|---|
| decision | string | decision: "block" provides Hook error feedback to subsequent processing; it does not guarantee hiding the original result and does not undo operations already performed. |
| reason | string | Reason for blocking the result |
| hookSpecificOutput.additionalContext | string | Additional explanation for the model |
| hookSpecificOutput.updatedToolOutput | string | Replacement tool-output text |
| hookSpecificOutput.updatedMCPToolOutput | string | MCP-only compatibility replacement field; prefer updatedToolOutput |
Stop
Triggered when the Agent is about to finish the current turn, to check delivery conditions. block means “do not finish yet; continue working”.
Request body:
| Field | Type | Description |
|---|---|---|
| stop_hook_active | boolean | Whether a Stop Hook has already required further work; true when the Agent is about to finish again |
| last_assistant_message | string, optional | Accumulated Agent text output for this turn |
| Response field | Type | Description |
|---|---|---|
| decision | string | block prevents normal completion and requires the Agent to continue; {} allows completion |
| reason | string | Specific remaining work the Agent must perform |
Notification
Triggered for notifications such as permission confirmation and MCP elicitation. matcher matches notification_type, not the tool name.
Request body:
| Field | Type | Description |
|---|---|---|
| notification_type | string | Notification type; see the values below |
| message | string | Notification body |
| details | object | Notification details; structure varies by type |
| Value | Meaning |
|---|---|
| permission_prompt | Permission confirmation requested |
| elicitation_dialog | MCP elicitation started |
| elicitation_response | MCP elicitation response received |
| elicitation_complete | MCP elicitation completed |
PreCompact
Triggered before actual manual or automatic context compaction, not on every conversation turn. matcher matches trigger.
Request body:
| Field | Type | Description |
|---|---|---|
| trigger | string | manual: manual compaction; auto: automatic compaction. |
| custom_instructions | string | Custom instructions for this compaction, or an empty string if none. |
Prevent this compaction:
| Response field | Type | Description |
|---|---|---|
| decision | string | deny prevents this compaction; return {} for no intervention. This event does not use the allow / block approval format. |
| reason | string | Reason for preventing compaction. |
PostCompact
Triggered after successful context compaction to receive its summary. Failed or prevented compaction does not trigger a success notification. matcher matches trigger.
Request body:
| Field | Type | Description |
|---|---|---|
| trigger | string | manual: manual compaction; auto: automatic compaction. |
| compact_summary | string | Summary of this compaction; may be empty. |
Return {} after receipt. This event cannot undo compaction. This guide does not define response fields for replacing the summary or injecting context. Verify actual triggering against the delivered version during integration testing.
ConnectorAdded
Reviews a connector's pending configuration, covering controlled creation, import, marketplace installation, enabling, and configuration updates. After a valid block, the client does not register, enable, or apply the update; previously effective configuration is not undone.
Request body:
| Field | Type | Description |
|---|---|---|
| source | string | Source: marketplace (marketplace installation), local_import (local import or installation after creation in a conversation), manual_config (manual configuration and similar entries), or console (delivered by the enterprise console). Filled by the client. |
| content_digest | string | SHA-256 hexadecimal digest of the pending content, used to correlate the review snapshot; not a download URL. |
| connector | object | Pending connector configuration; see its fields below. |
| connector field | Type | Description |
|---|---|---|
| name | string | Connector name. |
| kind | string | mcp or builtin. |
| config | object | Redacted copy of the actual pending configuration. HTTP connectors include the address; local command connectors include actual configuration such as command and args. Structure varies by connector type. |
| redacted_fields | string[] | Paths of sensitive fields that have been hidden; empty array if none. |
Reject:
This event reviews configuration additions; it does not replace subsequent PreToolUse checks for tool calls.
| Response field | Type | Description |
|---|---|---|
| decision | string | Required; only allow or block. allow continues adding; block prevents this operation. |
| reason | string | Allowed only with block; required and nonblank. The client displays it as plain text. |
ExpertSuiteAdded
Reviews the complete file snapshot before plugin installation, including the manifest, skills, scripts, and other resources. Reading the review content does not execute package scripts.
Request body:
| Field | Type | Description |
|---|---|---|
| source | string | Source: marketplace (marketplace installation), local_import (local import or installation after creation in a conversation), manual_config (manual configuration and similar entries), or console (delivered by the enterprise console). Filled by the client. |
| content_digest | string | SHA-256 hexadecimal digest of the pending content, used to correlate the review snapshot; not a download URL. |
| expert_suite | object | Plugin to install; see its fields below. |
| expert_suite field | Type | Description |
|---|---|---|
| name | string | Plugin name. |
| version | string, may be omitted | Omitted if the package declares no version. |
| manifest | object | Actual parsed package manifest. |
| files | array | Complete pending file snapshot, each item containing path, encoding, and content. The example only illustrates the file structure. |
| File field | Type | Description |
|---|---|---|
| files[].path | string | Relative path within the package; not a local path or download URL the server can read directly. |
| files[].encoding | string | Must be base64. |
| files[].content | string | Base64-encoded complete file content; decode it on the server for inspection. |
Reject:
If rejected, this plugin is not installed or activated. The client displays reason as plain text without adding an “Import plugin failed” prefix.
| Response field | Type | Description |
|---|---|---|
| decision | string | Required; only allow or block. allow continues adding; block prevents this operation. |
| reason | string | Allowed only with block; required and nonblank. The client displays it as plain text. |
SkillAdded
Reviews the complete file snapshot before skill installation, including SKILL.md, scripts, references, and other resources, not just the skill description.
Request body:
| Field | Type | Description |
|---|---|---|
| source | string | Source: marketplace (marketplace installation), local_import (local import or installation after creation in a conversation), manual_config (manual configuration and similar entries), or console (delivered by the enterprise console). Filled by the client. |
| content_digest | string | SHA-256 hexadecimal digest of the pending content, used to correlate the review snapshot; not a download URL. |
| skill | object | Skill to install; see its fields below. |
| skill field | Type | Description |
|---|---|---|
| name | string | Skill name. |
| version | string, may be omitted | Omitted if skill metadata declares no version. |
| files | array | Complete pending file snapshot, each item containing path, encoding, and content. |
| File field | Type | Description |
|---|---|---|
| files[].path | string | Relative path within the package; not a local path or download URL the server can read directly. |
| files[].encoding | string | Must be base64. |
| files[].content | string | Base64-encoded complete file content; decode it on the server for inspection. |
Reject:
If rejected, this skill is not installed into the active directory. As with connectors and plugins, the client displays reason directly rather than replacing it with a generic upload failure message.
| Response field | Type | Description |
|---|---|---|
| decision | string | Required; only allow or block. allow continues adding; block prevents this operation. |
| reason | string | Allowed only with block; required and nonblank. The client displays it as plain text. |