Merge branch 'codex/simp-session-dead-surface' into codex/simp-session-log-representation
This commit is contained in:
@@ -15,6 +15,9 @@
|
||||
* @module @deepseek-ai/dsh-hooks-codex
|
||||
*/
|
||||
|
||||
// Each dialect bridge keeps its complete dependency list visible at the entry
|
||||
// point; a cross-package facade for imports alone would add indirection.
|
||||
/* jscpd:ignore-start */
|
||||
import { readFileSync } from 'node:fs'
|
||||
import type { Context } from 'cordis'
|
||||
import z from 'schemastery'
|
||||
@@ -35,6 +38,7 @@ import {
|
||||
type MergedHookOutcome,
|
||||
} from '@deepseek-ai/dsh-hook-protocol'
|
||||
import { parseCodexConfig, type CodexHookConfig } from './config.ts'
|
||||
/* jscpd:ignore-end */
|
||||
|
||||
export const name = 'hooks-codex'
|
||||
export const inject = ['bash']
|
||||
|
||||
@@ -874,7 +874,7 @@ describe('scoped-dispatch invariants', () => {
|
||||
['tools/result', [{ callId: 'c', name: 't', arguments: {}, agent }, { callId: 'c', content: [], isError: false }]],
|
||||
]
|
||||
for (const [event, args] of rows) {
|
||||
const subject = event.startsWith('tools/') ? agent : agent
|
||||
const subject = agent
|
||||
expect(() => { (ctx.emit as (...a: unknown[]) => void)(scopeTarget(agent, subject), event, ...args) },
|
||||
`${event} with matching carrier`).not.toThrow()
|
||||
expect(() => { (ctx.emit as (...a: unknown[]) => void)(scopeTarget(agent, other), event, ...args) },
|
||||
|
||||
@@ -64,6 +64,9 @@ export interface Config {
|
||||
skills?: agentCore.SkillConfig
|
||||
}
|
||||
|
||||
// Each front door owns a complete, directly readable config schema; extracting
|
||||
// the common fields would make two small app contracts depend on a new facade.
|
||||
/* jscpd:ignore-start */
|
||||
export const Config: z<Config> = z.object({
|
||||
model: z.string().required(),
|
||||
persona: z.string(),
|
||||
@@ -77,6 +80,7 @@ export const Config: z<Config> = z.object({
|
||||
persistenceRoot: z.string().default('./.sessions'),
|
||||
skills: agentCore.SkillConfigSchema,
|
||||
})
|
||||
/* jscpd:ignore-end */
|
||||
|
||||
/**
|
||||
* Compose the spine with the ACP front door. The agent-core bundle pre-creates
|
||||
|
||||
@@ -99,12 +99,16 @@ export class PerplexitySearchProvider implements WebSearchProvider {
|
||||
|
||||
constructor(private readonly options: PerplexitySearchProviderOptions) {}
|
||||
|
||||
// Availability checks stay beside each provider's distinct config contract;
|
||||
// a shared base class would obscure which fields make this backend usable.
|
||||
/* jscpd:ignore-start */
|
||||
status(): WebProviderStatus {
|
||||
if (this.options.apiKey.length === 0) return { available: false, reason: 'missing-credential' }
|
||||
if (!URL.canParse(this.options.baseURL)) return { available: false, reason: 'misconfigured' }
|
||||
if (!isPositiveInteger(this.options.maxTokens)) return { available: false, reason: 'misconfigured' }
|
||||
return { available: true }
|
||||
}
|
||||
/* jscpd:ignore-end */
|
||||
|
||||
async search(request: WebSearchRequest, exec?: { readonly signal?: AbortSignal }): Promise<WebSearchResult> {
|
||||
let response: Response
|
||||
@@ -159,6 +163,9 @@ export class PerplexitySearchProvider implements WebSearchProvider {
|
||||
}
|
||||
}
|
||||
|
||||
// These two predicates are intentionally local: exporting generic internals
|
||||
// from the public web seam would cost more API surface than these pure checks.
|
||||
/* jscpd:ignore-start */
|
||||
/** True for a fetch/`AbortSignal` abort, surfaced as `WEB_ABORTED`. */
|
||||
function isAbortError(error: unknown): boolean {
|
||||
return error instanceof DOMException && error.name === 'AbortError'
|
||||
@@ -168,3 +175,4 @@ function isAbortError(error: unknown): boolean {
|
||||
function isPositiveInteger(value: number): boolean {
|
||||
return Number.isInteger(value) && value > 0
|
||||
}
|
||||
/* jscpd:ignore-end */
|
||||
|
||||
Reference in New Issue
Block a user