fixo-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +530 -0
- package/dist/agent/agent-client.d.ts +108 -0
- package/dist/agent/agent-client.d.ts.map +1 -0
- package/dist/agent/agent-client.js +1247 -0
- package/dist/agent/agent-client.js.map +1 -0
- package/dist/agent/agent-pool.d.ts +20 -0
- package/dist/agent/agent-pool.d.ts.map +1 -0
- package/dist/agent/agent-pool.js +217 -0
- package/dist/agent/agent-pool.js.map +1 -0
- package/dist/agent/background-awareness.d.ts +55 -0
- package/dist/agent/background-awareness.d.ts.map +1 -0
- package/dist/agent/background-awareness.js +104 -0
- package/dist/agent/background-awareness.js.map +1 -0
- package/dist/agent/command-parser.d.ts +33 -0
- package/dist/agent/command-parser.d.ts.map +1 -0
- package/dist/agent/command-parser.js +120 -0
- package/dist/agent/command-parser.js.map +1 -0
- package/dist/agent/context-budget.d.ts +91 -0
- package/dist/agent/context-budget.d.ts.map +1 -0
- package/dist/agent/context-budget.js +219 -0
- package/dist/agent/context-budget.js.map +1 -0
- package/dist/agent/conversation.d.ts +190 -0
- package/dist/agent/conversation.d.ts.map +1 -0
- package/dist/agent/conversation.js +547 -0
- package/dist/agent/conversation.js.map +1 -0
- package/dist/agent/hooks.d.ts +72 -0
- package/dist/agent/hooks.d.ts.map +1 -0
- package/dist/agent/hooks.js +214 -0
- package/dist/agent/hooks.js.map +1 -0
- package/dist/agent/mcp-bridge.d.ts +13 -0
- package/dist/agent/mcp-bridge.d.ts.map +1 -0
- package/dist/agent/mcp-bridge.js +86 -0
- package/dist/agent/mcp-bridge.js.map +1 -0
- package/dist/agent/mcp-client.d.ts +24 -0
- package/dist/agent/mcp-client.d.ts.map +1 -0
- package/dist/agent/mcp-client.js +146 -0
- package/dist/agent/mcp-client.js.map +1 -0
- package/dist/agent/mcp-manager.d.ts +13 -0
- package/dist/agent/mcp-manager.d.ts.map +1 -0
- package/dist/agent/mcp-manager.js +84 -0
- package/dist/agent/mcp-manager.js.map +1 -0
- package/dist/agent/mcp-registry.d.ts +45 -0
- package/dist/agent/mcp-registry.d.ts.map +1 -0
- package/dist/agent/mcp-registry.js +98 -0
- package/dist/agent/mcp-registry.js.map +1 -0
- package/dist/agent/orchestrator.d.ts +14 -0
- package/dist/agent/orchestrator.d.ts.map +1 -0
- package/dist/agent/orchestrator.js +118 -0
- package/dist/agent/orchestrator.js.map +1 -0
- package/dist/agent/parser-adapter.d.ts +120 -0
- package/dist/agent/parser-adapter.d.ts.map +1 -0
- package/dist/agent/parser-adapter.js +265 -0
- package/dist/agent/parser-adapter.js.map +1 -0
- package/dist/agent/parsers/imports.d.ts +11 -0
- package/dist/agent/parsers/imports.d.ts.map +1 -0
- package/dist/agent/parsers/imports.js +94 -0
- package/dist/agent/parsers/imports.js.map +1 -0
- package/dist/agent/parsers/shell.d.ts +23 -0
- package/dist/agent/parsers/shell.d.ts.map +1 -0
- package/dist/agent/parsers/shell.js +200 -0
- package/dist/agent/parsers/shell.js.map +1 -0
- package/dist/agent/parsers/symbols.d.ts +17 -0
- package/dist/agent/parsers/symbols.d.ts.map +1 -0
- package/dist/agent/parsers/symbols.js +103 -0
- package/dist/agent/parsers/symbols.js.map +1 -0
- package/dist/agent/permissions.d.ts +65 -0
- package/dist/agent/permissions.d.ts.map +1 -0
- package/dist/agent/permissions.js +219 -0
- package/dist/agent/permissions.js.map +1 -0
- package/dist/agent/predictive-gate.d.ts +69 -0
- package/dist/agent/predictive-gate.d.ts.map +1 -0
- package/dist/agent/predictive-gate.js +128 -0
- package/dist/agent/predictive-gate.js.map +1 -0
- package/dist/agent/provider-cooldown.d.ts +144 -0
- package/dist/agent/provider-cooldown.d.ts.map +1 -0
- package/dist/agent/provider-cooldown.js +300 -0
- package/dist/agent/provider-cooldown.js.map +1 -0
- package/dist/agent/providers-manager.d.ts +109 -0
- package/dist/agent/providers-manager.d.ts.map +1 -0
- package/dist/agent/providers-manager.js +464 -0
- package/dist/agent/providers-manager.js.map +1 -0
- package/dist/agent/repo-map.d.ts +6 -0
- package/dist/agent/repo-map.d.ts.map +1 -0
- package/dist/agent/repo-map.js +221 -0
- package/dist/agent/repo-map.js.map +1 -0
- package/dist/agent/retry.d.ts +103 -0
- package/dist/agent/retry.d.ts.map +1 -0
- package/dist/agent/retry.js +276 -0
- package/dist/agent/retry.js.map +1 -0
- package/dist/agent/search/index.d.ts +61 -0
- package/dist/agent/search/index.d.ts.map +1 -0
- package/dist/agent/search/index.js +314 -0
- package/dist/agent/search/index.js.map +1 -0
- package/dist/agent/single-agent.d.ts +76 -0
- package/dist/agent/single-agent.d.ts.map +1 -0
- package/dist/agent/single-agent.js +697 -0
- package/dist/agent/single-agent.js.map +1 -0
- package/dist/agent/skills.d.ts +22 -0
- package/dist/agent/skills.d.ts.map +1 -0
- package/dist/agent/skills.js +139 -0
- package/dist/agent/skills.js.map +1 -0
- package/dist/agent/stream-glue.d.ts +85 -0
- package/dist/agent/stream-glue.d.ts.map +1 -0
- package/dist/agent/stream-glue.js +120 -0
- package/dist/agent/stream-glue.js.map +1 -0
- package/dist/agent/subagent.d.ts +72 -0
- package/dist/agent/subagent.d.ts.map +1 -0
- package/dist/agent/subagent.js +193 -0
- package/dist/agent/subagent.js.map +1 -0
- package/dist/agent/telemetry.d.ts +192 -0
- package/dist/agent/telemetry.d.ts.map +1 -0
- package/dist/agent/telemetry.js +400 -0
- package/dist/agent/telemetry.js.map +1 -0
- package/dist/agent/tokenizer.d.ts +42 -0
- package/dist/agent/tokenizer.d.ts.map +1 -0
- package/dist/agent/tokenizer.js +107 -0
- package/dist/agent/tokenizer.js.map +1 -0
- package/dist/agent/tool-executor.d.ts +289 -0
- package/dist/agent/tool-executor.d.ts.map +1 -0
- package/dist/agent/tool-executor.js +2519 -0
- package/dist/agent/tool-executor.js.map +1 -0
- package/dist/agent/web-impl.d.ts +2 -0
- package/dist/agent/web-impl.d.ts.map +1 -0
- package/dist/agent/web-impl.js +34 -0
- package/dist/agent/web-impl.js.map +1 -0
- package/dist/agent/web.d.ts +8 -0
- package/dist/agent/web.d.ts.map +1 -0
- package/dist/agent/web.js +8 -0
- package/dist/agent/web.js.map +1 -0
- package/dist/agent/worker-agent.d.ts +27 -0
- package/dist/agent/worker-agent.d.ts.map +1 -0
- package/dist/agent/worker-agent.js +503 -0
- package/dist/agent/worker-agent.js.map +1 -0
- package/dist/config.d.ts +162 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +138 -0
- package/dist/config.js.map +1 -0
- package/dist/context/fixo-md-watcher.d.ts +42 -0
- package/dist/context/fixo-md-watcher.d.ts.map +1 -0
- package/dist/context/fixo-md-watcher.js +126 -0
- package/dist/context/fixo-md-watcher.js.map +1 -0
- package/dist/context/fixo-md.d.ts +50 -0
- package/dist/context/fixo-md.d.ts.map +1 -0
- package/dist/context/fixo-md.js +118 -0
- package/dist/context/fixo-md.js.map +1 -0
- package/dist/context/todo.d.ts +65 -0
- package/dist/context/todo.d.ts.map +1 -0
- package/dist/context/todo.js +194 -0
- package/dist/context/todo.js.map +1 -0
- package/dist/git/git-manager.d.ts +33 -0
- package/dist/git/git-manager.d.ts.map +1 -0
- package/dist/git/git-manager.js +293 -0
- package/dist/git/git-manager.js.map +1 -0
- package/dist/git/git-ops.d.ts +10 -0
- package/dist/git/git-ops.d.ts.map +1 -0
- package/dist/git/git-ops.js +131 -0
- package/dist/git/git-ops.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +352 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer.d.ts +30 -0
- package/dist/indexer.d.ts.map +1 -0
- package/dist/indexer.js +273 -0
- package/dist/indexer.js.map +1 -0
- package/dist/lsp/lsp-client.d.ts +24 -0
- package/dist/lsp/lsp-client.d.ts.map +1 -0
- package/dist/lsp/lsp-client.js +205 -0
- package/dist/lsp/lsp-client.js.map +1 -0
- package/dist/lsp/lsp-manager.d.ts +17 -0
- package/dist/lsp/lsp-manager.d.ts.map +1 -0
- package/dist/lsp/lsp-manager.js +154 -0
- package/dist/lsp/lsp-manager.js.map +1 -0
- package/dist/lsp/lsp-pre-save.d.ts +137 -0
- package/dist/lsp/lsp-pre-save.d.ts.map +1 -0
- package/dist/lsp/lsp-pre-save.js +245 -0
- package/dist/lsp/lsp-pre-save.js.map +1 -0
- package/dist/lsp/syntax-fallback.d.ts +83 -0
- package/dist/lsp/syntax-fallback.d.ts.map +1 -0
- package/dist/lsp/syntax-fallback.js +275 -0
- package/dist/lsp/syntax-fallback.js.map +1 -0
- package/dist/model-outcomes.d.ts +12 -0
- package/dist/model-outcomes.d.ts.map +1 -0
- package/dist/model-outcomes.js +46 -0
- package/dist/model-outcomes.js.map +1 -0
- package/dist/planner.d.ts +32 -0
- package/dist/planner.d.ts.map +1 -0
- package/dist/planner.js +163 -0
- package/dist/planner.js.map +1 -0
- package/dist/project-memory.d.ts +29 -0
- package/dist/project-memory.d.ts.map +1 -0
- package/dist/project-memory.js +349 -0
- package/dist/project-memory.js.map +1 -0
- package/dist/review.d.ts +2 -0
- package/dist/review.d.ts.map +1 -0
- package/dist/review.js +61 -0
- package/dist/review.js.map +1 -0
- package/dist/runtime/background-jobs.d.ts +97 -0
- package/dist/runtime/background-jobs.d.ts.map +1 -0
- package/dist/runtime/background-jobs.js +331 -0
- package/dist/runtime/background-jobs.js.map +1 -0
- package/dist/runtime/credential-vault.d.ts +124 -0
- package/dist/runtime/credential-vault.d.ts.map +1 -0
- package/dist/runtime/credential-vault.js +184 -0
- package/dist/runtime/credential-vault.js.map +1 -0
- package/dist/runtime/loop-trap.d.ts +197 -0
- package/dist/runtime/loop-trap.d.ts.map +1 -0
- package/dist/runtime/loop-trap.js +420 -0
- package/dist/runtime/loop-trap.js.map +1 -0
- package/dist/runtime/policy.d.ts +15 -0
- package/dist/runtime/policy.d.ts.map +1 -0
- package/dist/runtime/policy.js +60 -0
- package/dist/runtime/policy.js.map +1 -0
- package/dist/runtime/redaction.d.ts +66 -0
- package/dist/runtime/redaction.d.ts.map +1 -0
- package/dist/runtime/redaction.js +155 -0
- package/dist/runtime/redaction.js.map +1 -0
- package/dist/runtime/session-snapshots.d.ts +76 -0
- package/dist/runtime/session-snapshots.d.ts.map +1 -0
- package/dist/runtime/session-snapshots.js +166 -0
- package/dist/runtime/session-snapshots.js.map +1 -0
- package/dist/runtime/staging.d.ts +205 -0
- package/dist/runtime/staging.d.ts.map +1 -0
- package/dist/runtime/staging.js +526 -0
- package/dist/runtime/staging.js.map +1 -0
- package/dist/runtime/task-session.d.ts +95 -0
- package/dist/runtime/task-session.d.ts.map +1 -0
- package/dist/runtime/task-session.js +263 -0
- package/dist/runtime/task-session.js.map +1 -0
- package/dist/runtime/worktree.d.ts +55 -0
- package/dist/runtime/worktree.d.ts.map +1 -0
- package/dist/runtime/worktree.js +175 -0
- package/dist/runtime/worktree.js.map +1 -0
- package/dist/setup-wizard.d.ts +8 -0
- package/dist/setup-wizard.d.ts.map +1 -0
- package/dist/setup-wizard.js +73 -0
- package/dist/setup-wizard.js.map +1 -0
- package/dist/shared/content.d.ts +43 -0
- package/dist/shared/content.d.ts.map +1 -0
- package/dist/shared/content.js +61 -0
- package/dist/shared/content.js.map +1 -0
- package/dist/shared/types.d.ts +217 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +3 -0
- package/dist/shared/types.js.map +1 -0
- package/dist/test-runner.d.ts +5 -0
- package/dist/test-runner.d.ts.map +1 -0
- package/dist/test-runner.js +42 -0
- package/dist/test-runner.js.map +1 -0
- package/dist/types.d.ts +85 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/ascii.d.ts +23 -0
- package/dist/ui/ascii.d.ts.map +1 -0
- package/dist/ui/ascii.js +45 -0
- package/dist/ui/ascii.js.map +1 -0
- package/dist/ui/colors.d.ts +111 -0
- package/dist/ui/colors.d.ts.map +1 -0
- package/dist/ui/colors.js +166 -0
- package/dist/ui/colors.js.map +1 -0
- package/dist/ui/image-attach.d.ts +27 -0
- package/dist/ui/image-attach.d.ts.map +1 -0
- package/dist/ui/image-attach.js +100 -0
- package/dist/ui/image-attach.js.map +1 -0
- package/dist/ui/index.d.ts +18 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +18 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/markdown-stream.d.ts +91 -0
- package/dist/ui/markdown-stream.d.ts.map +1 -0
- package/dist/ui/markdown-stream.js +524 -0
- package/dist/ui/markdown-stream.js.map +1 -0
- package/dist/ui/plan-renderer.d.ts +36 -0
- package/dist/ui/plan-renderer.d.ts.map +1 -0
- package/dist/ui/plan-renderer.js +79 -0
- package/dist/ui/plan-renderer.js.map +1 -0
- package/dist/ui/prompt.d.ts +11 -0
- package/dist/ui/prompt.d.ts.map +1 -0
- package/dist/ui/prompt.js +1960 -0
- package/dist/ui/prompt.js.map +1 -0
- package/dist/ui/render-primitives.d.ts +117 -0
- package/dist/ui/render-primitives.d.ts.map +1 -0
- package/dist/ui/render-primitives.js +322 -0
- package/dist/ui/render-primitives.js.map +1 -0
- package/dist/ui/render.d.ts +133 -0
- package/dist/ui/render.d.ts.map +1 -0
- package/dist/ui/render.js +547 -0
- package/dist/ui/render.js.map +1 -0
- package/dist/ui/session-header.d.ts +30 -0
- package/dist/ui/session-header.d.ts.map +1 -0
- package/dist/ui/session-header.js +74 -0
- package/dist/ui/session-header.js.map +1 -0
- package/dist/workspace-guard.d.ts +68 -0
- package/dist/workspace-guard.d.ts.map +1 -0
- package/dist/workspace-guard.js +168 -0
- package/dist/workspace-guard.js.map +1 -0
- package/dist/workspace-lock.d.ts +27 -0
- package/dist/workspace-lock.d.ts.map +1 -0
- package/dist/workspace-lock.js +95 -0
- package/dist/workspace-lock.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export interface SearchResult {
|
|
2
|
+
readonly title: string;
|
|
3
|
+
readonly url: string;
|
|
4
|
+
readonly snippet: string;
|
|
5
|
+
readonly score?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface SearchOptions {
|
|
8
|
+
readonly maxResults?: number;
|
|
9
|
+
readonly signal?: AbortSignal;
|
|
10
|
+
}
|
|
11
|
+
export interface SearchProvider {
|
|
12
|
+
readonly id: 'brave' | 'tavily' | 'ddg';
|
|
13
|
+
/**
|
|
14
|
+
* True if the provider can run right now (key configured, not
|
|
15
|
+
* currently rate-limited). The chain uses this to skip a
|
|
16
|
+
* provider without paying the cost of an HTTP round-trip.
|
|
17
|
+
*/
|
|
18
|
+
isAvailable(): Promise<boolean>;
|
|
19
|
+
search(query: string, opts?: SearchOptions): Promise<SearchResult[]>;
|
|
20
|
+
}
|
|
21
|
+
export declare class SearchExhaustedError extends Error {
|
|
22
|
+
readonly query: string;
|
|
23
|
+
readonly attempts: ReadonlyArray<{
|
|
24
|
+
provider: string;
|
|
25
|
+
error: string;
|
|
26
|
+
}>;
|
|
27
|
+
constructor(query: string, attempts: ReadonlyArray<{
|
|
28
|
+
provider: string;
|
|
29
|
+
error: string;
|
|
30
|
+
}>);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Default provider chain: Brave → Tavily → DDG fallback. The
|
|
34
|
+
* order is hard-coded; if you need a different order, construct
|
|
35
|
+
* a custom {@link SearchProviderChain} via the named-arg form.
|
|
36
|
+
*/
|
|
37
|
+
export declare class SearchProviderChain {
|
|
38
|
+
private readonly providers;
|
|
39
|
+
private readonly onProviderTried?;
|
|
40
|
+
constructor(providers?: SearchProvider[], hooks?: {
|
|
41
|
+
onProviderTried?: (provider: string, results: number, durationMs: number) => void;
|
|
42
|
+
});
|
|
43
|
+
search(query: string, opts?: SearchOptions): Promise<{
|
|
44
|
+
results: SearchResult[];
|
|
45
|
+
provider: SearchProvider['id'] | null;
|
|
46
|
+
attempts: Array<{
|
|
47
|
+
provider: string;
|
|
48
|
+
error: string;
|
|
49
|
+
}>;
|
|
50
|
+
}>;
|
|
51
|
+
}
|
|
52
|
+
export declare function getDefaultSearchChain(): SearchProviderChain;
|
|
53
|
+
/** Test hook — drop the cached chain. */
|
|
54
|
+
export declare function resetDefaultSearchChain(): void;
|
|
55
|
+
/**
|
|
56
|
+
* High-level "search the web" entry point. Backwards-compatible
|
|
57
|
+
* with the legacy `webSearch(query)` signature so existing tool
|
|
58
|
+
* dispatch and tests keep working.
|
|
59
|
+
*/
|
|
60
|
+
export declare function webSearch(query: string): Promise<string>;
|
|
61
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/search/index.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACxC;;;;OAIG;IACH,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CACtE;AAID,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,SAAgB,KAAK,EAAE,MAAM,CAAC;IAC9B,SAAgB,QAAQ,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;gBAE3E,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAU/D;AAmOD;;;;GAIG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAC7C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAkE;gBAGjG,SAAS,CAAC,EAAE,cAAc,EAAE,EAC5B,KAAK,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE;IAOlF,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC;QACpE,OAAO,EAAE,YAAY,EAAE,CAAC;QACxB,QAAQ,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACtC,QAAQ,EAAE,KAAK,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACtD,CAAC;CA4BH;AAID,wBAAgB,qBAAqB,IAAI,mBAAmB,CAG3D;AAED,yCAAyC;AACzC,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAkBD;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAU9D"}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reliable web search — provider chain.
|
|
3
|
+
*
|
|
4
|
+
* The original `src/agent/web.ts` (Phase 0) reached DuckDuckGo
|
|
5
|
+
* directly via HTML scraping. The DDG endpoint is rate-limited,
|
|
6
|
+
* geo-fenced, and silently changes its DOM. Phase 2 replaces
|
|
7
|
+
* it with a typed provider chain that prefers first-party
|
|
8
|
+
* search APIs (Brave, then Tavily) and falls back to DDG
|
|
9
|
+
* only when no API key is configured. The chain records
|
|
10
|
+
* per-provider quality scores so the cooldown manager can
|
|
11
|
+
* prefer whichever provider is currently responding fastest.
|
|
12
|
+
*
|
|
13
|
+
* Pillar 4 (credential vault) is preserved by reading every
|
|
14
|
+
* API key through {@link getProviderKeyVault}.withApiKey so
|
|
15
|
+
* the key never escapes the callback scope and never
|
|
16
|
+
* appears in tool results, telemetry, or error messages.
|
|
17
|
+
*/
|
|
18
|
+
import { withRetry, defaultIsRetryable } from '../retry.js';
|
|
19
|
+
import { getProviderKeyVault, ProviderNotInVaultError } from '../../runtime/credential-vault.js';
|
|
20
|
+
import { recordProviderError, recordProviderQuality, } from '../provider-cooldown.js';
|
|
21
|
+
import * as cheerio from 'cheerio';
|
|
22
|
+
/* ──────────────────────── Errors ──────────────────────── */
|
|
23
|
+
export class SearchExhaustedError extends Error {
|
|
24
|
+
query;
|
|
25
|
+
attempts;
|
|
26
|
+
constructor(query, attempts) {
|
|
27
|
+
super(`All search providers failed for query "${query}". ` +
|
|
28
|
+
`Tried: ${attempts.map((a) => a.provider).join(' → ')}.`);
|
|
29
|
+
this.name = 'SearchExhaustedError';
|
|
30
|
+
this.query = query;
|
|
31
|
+
this.attempts = attempts;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/* ──────────────────────── Brave ──────────────────────── */
|
|
35
|
+
const BRAVE_PROVIDER_NAME = 'search.brave';
|
|
36
|
+
const BRAVE_ENDPOINT = 'https://api.search.brave.com/res/v1/web/search';
|
|
37
|
+
const BRAVE_KEY_NOT_CONFIGURED = '__not_configured__';
|
|
38
|
+
class BraveProvider {
|
|
39
|
+
id = 'brave';
|
|
40
|
+
async isAvailable() {
|
|
41
|
+
try {
|
|
42
|
+
return await getProviderKeyVault().hasProvider(BRAVE_PROVIDER_NAME);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async search(query, opts = {}) {
|
|
49
|
+
const maxResults = opts.maxResults ?? 10;
|
|
50
|
+
const t0 = Date.now();
|
|
51
|
+
return await withRetry(async (signal) => {
|
|
52
|
+
const headers = await getProviderKeyVault().buildAuthHeaders(BRAVE_PROVIDER_NAME, (cred) => ({
|
|
53
|
+
'X-Subscription-Token': cred.apiKey,
|
|
54
|
+
'Accept': 'application/json',
|
|
55
|
+
'User-Agent': 'FixO-CLI/2.0 (search)',
|
|
56
|
+
}));
|
|
57
|
+
const url = new URL(BRAVE_ENDPOINT);
|
|
58
|
+
url.searchParams.set('q', query);
|
|
59
|
+
url.searchParams.set('count', String(Math.min(maxResults, 20)));
|
|
60
|
+
const response = await fetch(url.toString(), {
|
|
61
|
+
method: 'GET',
|
|
62
|
+
headers,
|
|
63
|
+
signal,
|
|
64
|
+
});
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
const status = response.status;
|
|
67
|
+
recordProviderError('brave', status, `HTTP ${status} ${response.statusText}`);
|
|
68
|
+
if (status === 401 || status === 403) {
|
|
69
|
+
throw new ProviderNotInVaultError(BRAVE_PROVIDER_NAME);
|
|
70
|
+
}
|
|
71
|
+
throw new Error(`Brave HTTP ${status}`);
|
|
72
|
+
}
|
|
73
|
+
const json = (await response.json());
|
|
74
|
+
const results = (json.web?.results ?? [])
|
|
75
|
+
.filter((r) => r.title && r.url)
|
|
76
|
+
.slice(0, maxResults)
|
|
77
|
+
.map((r) => ({
|
|
78
|
+
title: r.title ?? '',
|
|
79
|
+
url: r.url ?? '',
|
|
80
|
+
snippet: r.description ?? '',
|
|
81
|
+
}));
|
|
82
|
+
recordProviderQuality('brave', Date.now() - t0, results.length);
|
|
83
|
+
return results;
|
|
84
|
+
}, {
|
|
85
|
+
maxAttempts: 2,
|
|
86
|
+
baseDelayMs: 500,
|
|
87
|
+
maxDelayMs: 4_000,
|
|
88
|
+
jitter: 'full',
|
|
89
|
+
isRetryable: (err) => {
|
|
90
|
+
if (err instanceof ProviderNotInVaultError)
|
|
91
|
+
return false;
|
|
92
|
+
return defaultIsRetryable(err);
|
|
93
|
+
},
|
|
94
|
+
}, opts.signal);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/* ──────────────────────── Tavily ──────────────────────── */
|
|
98
|
+
const TAVILY_PROVIDER_NAME = 'search.tavily';
|
|
99
|
+
const TAVILY_ENDPOINT = 'https://api.tavily.com/search';
|
|
100
|
+
class TavilyProvider {
|
|
101
|
+
id = 'tavily';
|
|
102
|
+
async isAvailable() {
|
|
103
|
+
try {
|
|
104
|
+
return await getProviderKeyVault().hasProvider(TAVILY_PROVIDER_NAME);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async search(query, opts = {}) {
|
|
111
|
+
const maxResults = opts.maxResults ?? 10;
|
|
112
|
+
const t0 = Date.now();
|
|
113
|
+
return await withRetry(async (signal) => {
|
|
114
|
+
const apiKey = await getProviderKeyVault().withApiKey(TAVILY_PROVIDER_NAME, async (key) => key);
|
|
115
|
+
const response = await fetch(TAVILY_ENDPOINT, {
|
|
116
|
+
method: 'POST',
|
|
117
|
+
headers: {
|
|
118
|
+
'Content-Type': 'application/json',
|
|
119
|
+
'User-Agent': 'FixO-CLI/2.0 (search)',
|
|
120
|
+
},
|
|
121
|
+
body: JSON.stringify({
|
|
122
|
+
api_key: apiKey,
|
|
123
|
+
query,
|
|
124
|
+
max_results: Math.min(maxResults, 20),
|
|
125
|
+
include_answer: false,
|
|
126
|
+
search_depth: 'basic',
|
|
127
|
+
}),
|
|
128
|
+
signal,
|
|
129
|
+
});
|
|
130
|
+
if (!response.ok) {
|
|
131
|
+
const status = response.status;
|
|
132
|
+
recordProviderError('tavily', status, `HTTP ${status} ${response.statusText}`);
|
|
133
|
+
if (status === 401 || status === 403) {
|
|
134
|
+
throw new ProviderNotInVaultError(TAVILY_PROVIDER_NAME);
|
|
135
|
+
}
|
|
136
|
+
throw new Error(`Tavily HTTP ${status}`);
|
|
137
|
+
}
|
|
138
|
+
const json = (await response.json());
|
|
139
|
+
const results = (json.results ?? [])
|
|
140
|
+
.filter((r) => r.title && r.url)
|
|
141
|
+
.slice(0, maxResults)
|
|
142
|
+
.map((r) => ({
|
|
143
|
+
title: r.title ?? '',
|
|
144
|
+
url: r.url ?? '',
|
|
145
|
+
snippet: r.content ?? '',
|
|
146
|
+
score: r.score,
|
|
147
|
+
}));
|
|
148
|
+
recordProviderQuality('tavily', Date.now() - t0, results.length);
|
|
149
|
+
return results;
|
|
150
|
+
}, {
|
|
151
|
+
maxAttempts: 2,
|
|
152
|
+
baseDelayMs: 500,
|
|
153
|
+
maxDelayMs: 4_000,
|
|
154
|
+
jitter: 'full',
|
|
155
|
+
isRetryable: (err) => {
|
|
156
|
+
if (err instanceof ProviderNotInVaultError)
|
|
157
|
+
return false;
|
|
158
|
+
return defaultIsRetryable(err);
|
|
159
|
+
},
|
|
160
|
+
}, opts.signal);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/* ──────────────────────── DDG fallback ──────────────────────── */
|
|
164
|
+
/**
|
|
165
|
+
* Original DDG HTML scraping path, refactored to implement
|
|
166
|
+
* {@link SearchProvider} so it can sit in the chain. Returns
|
|
167
|
+
* an empty result (not an error) when the page structure
|
|
168
|
+
* changes — a structural-change error is logged via
|
|
169
|
+
* `recordProviderError` and the chain moves to the next
|
|
170
|
+
* provider.
|
|
171
|
+
*/
|
|
172
|
+
class DdgProvider {
|
|
173
|
+
id = 'ddg';
|
|
174
|
+
async isAvailable() {
|
|
175
|
+
return true; // always available, no key required
|
|
176
|
+
}
|
|
177
|
+
async search(query, opts = {}) {
|
|
178
|
+
const maxResults = opts.maxResults ?? 10;
|
|
179
|
+
const t0 = Date.now();
|
|
180
|
+
const url = `https://html.duckduckgo.com/html/?q=${encodeURIComponent(query)}`;
|
|
181
|
+
const response = await fetch(url, {
|
|
182
|
+
method: 'GET',
|
|
183
|
+
headers: {
|
|
184
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' +
|
|
185
|
+
'(KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
|
|
186
|
+
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
|
187
|
+
},
|
|
188
|
+
signal: opts.signal,
|
|
189
|
+
});
|
|
190
|
+
if (!response.ok) {
|
|
191
|
+
const status = response.status;
|
|
192
|
+
recordProviderError('ddg', status, `HTTP ${status} ${response.statusText}`);
|
|
193
|
+
throw new Error(`DDG HTTP ${status}`);
|
|
194
|
+
}
|
|
195
|
+
const html = await response.text();
|
|
196
|
+
const $ = cheerio.load(html);
|
|
197
|
+
const results = [];
|
|
198
|
+
$('.result').each((_i, elem) => {
|
|
199
|
+
if (results.length >= maxResults)
|
|
200
|
+
return false;
|
|
201
|
+
const titleElem = $(elem).find('.result__title a');
|
|
202
|
+
const snippetElem = $(elem).find('.result__snippet');
|
|
203
|
+
if (titleElem.length === 0)
|
|
204
|
+
return;
|
|
205
|
+
let rawUrl = titleElem.attr('href') ?? '';
|
|
206
|
+
if (rawUrl.startsWith('//duckduckgo.com/l/?')) {
|
|
207
|
+
const m = rawUrl.match(/uddg=([^&]+)/);
|
|
208
|
+
if (m && m[1]) {
|
|
209
|
+
try {
|
|
210
|
+
rawUrl = decodeURIComponent(m[1]);
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
rawUrl = '';
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (!rawUrl)
|
|
218
|
+
return;
|
|
219
|
+
results.push({
|
|
220
|
+
title: titleElem.text().trim(),
|
|
221
|
+
url: rawUrl,
|
|
222
|
+
snippet: snippetElem.text().trim(),
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
recordProviderQuality('ddg', Date.now() - t0, results.length);
|
|
226
|
+
return results;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/* ──────────────────────── Chain ──────────────────────── */
|
|
230
|
+
/**
|
|
231
|
+
* Default provider chain: Brave → Tavily → DDG fallback. The
|
|
232
|
+
* order is hard-coded; if you need a different order, construct
|
|
233
|
+
* a custom {@link SearchProviderChain} via the named-arg form.
|
|
234
|
+
*/
|
|
235
|
+
export class SearchProviderChain {
|
|
236
|
+
providers;
|
|
237
|
+
onProviderTried;
|
|
238
|
+
constructor(providers, hooks) {
|
|
239
|
+
this.providers =
|
|
240
|
+
providers ?? [new BraveProvider(), new TavilyProvider(), new DdgProvider()];
|
|
241
|
+
this.onProviderTried = hooks?.onProviderTried;
|
|
242
|
+
}
|
|
243
|
+
async search(query, opts = {}) {
|
|
244
|
+
const attempts = [];
|
|
245
|
+
for (const provider of this.providers) {
|
|
246
|
+
const available = await provider.isAvailable();
|
|
247
|
+
if (!available) {
|
|
248
|
+
attempts.push({ provider: provider.id, error: 'not_configured' });
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
const t0 = Date.now();
|
|
252
|
+
try {
|
|
253
|
+
const results = await provider.search(query, opts);
|
|
254
|
+
const duration = Date.now() - t0;
|
|
255
|
+
this.onProviderTried?.(provider.id, results.length, duration);
|
|
256
|
+
if (results.length > 0) {
|
|
257
|
+
return { results, provider: provider.id, attempts };
|
|
258
|
+
}
|
|
259
|
+
attempts.push({ provider: provider.id, error: 'no_results' });
|
|
260
|
+
}
|
|
261
|
+
catch (err) {
|
|
262
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
263
|
+
attempts.push({ provider: provider.id, error: msg });
|
|
264
|
+
// Auth errors short-circuit — no point trying the next
|
|
265
|
+
// provider with a key the user hasn't configured.
|
|
266
|
+
if (err instanceof ProviderNotInVaultError)
|
|
267
|
+
continue;
|
|
268
|
+
// Otherwise keep trying the next provider.
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
throw new SearchExhaustedError(query, attempts);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
let cachedChain = null;
|
|
275
|
+
export function getDefaultSearchChain() {
|
|
276
|
+
if (!cachedChain)
|
|
277
|
+
cachedChain = new SearchProviderChain();
|
|
278
|
+
return cachedChain;
|
|
279
|
+
}
|
|
280
|
+
/** Test hook — drop the cached chain. */
|
|
281
|
+
export function resetDefaultSearchChain() {
|
|
282
|
+
cachedChain = null;
|
|
283
|
+
}
|
|
284
|
+
/* ──────────────────────── Markdown formatter (legacy surface) ───── */
|
|
285
|
+
function formatAsMarkdown(results, providerId) {
|
|
286
|
+
if (results.length === 0) {
|
|
287
|
+
return 'No results found.';
|
|
288
|
+
}
|
|
289
|
+
const header = providerId ? `_via ${providerId}_\n\n` : '';
|
|
290
|
+
const body = results
|
|
291
|
+
.map((r) => `### [${r.title}](${r.url})\n${r.snippet}\n`)
|
|
292
|
+
.join('\n');
|
|
293
|
+
return header + body;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* High-level "search the web" entry point. Backwards-compatible
|
|
297
|
+
* with the legacy `webSearch(query)` signature so existing tool
|
|
298
|
+
* dispatch and tests keep working.
|
|
299
|
+
*/
|
|
300
|
+
export async function webSearch(query) {
|
|
301
|
+
try {
|
|
302
|
+
const { results, provider } = await getDefaultSearchChain().search(query);
|
|
303
|
+
return formatAsMarkdown(results, provider);
|
|
304
|
+
}
|
|
305
|
+
catch (err) {
|
|
306
|
+
if (err instanceof SearchExhaustedError) {
|
|
307
|
+
return `No results found. Tried: ${err.attempts.map((a) => a.provider).join(', ')}.`;
|
|
308
|
+
}
|
|
309
|
+
return `Error performing web search: ${err instanceof Error ? err.message : String(err)}`;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
// Suppress unused-warning for the constant we keep around for symmetry.
|
|
313
|
+
void BRAVE_KEY_NOT_CONFIGURED;
|
|
314
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/agent/search/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { AgentClient } from './agent-client.js';
|
|
2
|
+
import { ConversationManager } from './conversation.js';
|
|
3
|
+
import type { AgentContext, AgentResult } from '../types.js';
|
|
4
|
+
import * as p from '@clack/prompts';
|
|
5
|
+
export declare const promptsWrapper: {
|
|
6
|
+
select: <Value>(opts: p.SelectOptions<Value>) => Promise<symbol | Value>;
|
|
7
|
+
confirm: (opts: p.ConfirmOptions) => Promise<boolean | symbol>;
|
|
8
|
+
spinner: () => {
|
|
9
|
+
start: (msg?: string) => void;
|
|
10
|
+
stop: (msg?: string, code?: number) => void;
|
|
11
|
+
message: (msg?: string) => void;
|
|
12
|
+
};
|
|
13
|
+
isCancel: typeof p.isCancel;
|
|
14
|
+
};
|
|
15
|
+
import type readline from 'readline';
|
|
16
|
+
export declare function evaluateInputIntent(task: string): 'CHAT_ONLY' | 'MUTATION';
|
|
17
|
+
export declare class SingleAgent {
|
|
18
|
+
private client;
|
|
19
|
+
private verbose;
|
|
20
|
+
private allowAll;
|
|
21
|
+
constructor(verbose?: boolean);
|
|
22
|
+
/** Expose the underlying client for direct API calls (e.g. compaction). */
|
|
23
|
+
getClient(): AgentClient;
|
|
24
|
+
runStreaming(context: AgentContext, conversation: ConversationManager, rl?: readline.Interface): Promise<AgentResult>;
|
|
25
|
+
/**
|
|
26
|
+
* Ask the user for permission to execute a tool.
|
|
27
|
+
* Prompts for every state-mutating tool: write_file,
|
|
28
|
+
* run_command, apply_patch, replace_range, insert_after,
|
|
29
|
+
* rename_file, delete_file, create_branch, commit_changes,
|
|
30
|
+
* push_branch, create_pull_request. Read-only tools (read_file,
|
|
31
|
+
* search_code, list_dir, extract_symbols, extract_imports)
|
|
32
|
+
* are auto-allowed.
|
|
33
|
+
*/
|
|
34
|
+
private askPermission;
|
|
35
|
+
/**
|
|
36
|
+
* Stream a text-only response to the terminal.
|
|
37
|
+
*
|
|
38
|
+
* Selects the resumable streaming path when `preferences.resilience.
|
|
39
|
+
* streamResume === 'auto'` (the default). Set it to `'never'` to
|
|
40
|
+
* fall back to the legacy non-resumable path — useful for tests
|
|
41
|
+
* that want to observe raw stream cuts.
|
|
42
|
+
*/
|
|
43
|
+
private streamResponse;
|
|
44
|
+
private executePureChatStream;
|
|
45
|
+
/**
|
|
46
|
+
* Auto-compact the conversation if the next request would approach the context limit.
|
|
47
|
+
* This is the core of the auto-context-management system.
|
|
48
|
+
*/
|
|
49
|
+
private autoCompactIfNeeded;
|
|
50
|
+
/**
|
|
51
|
+
* Pillar 4 — proactive context-budget enforcement.
|
|
52
|
+
*
|
|
53
|
+
* Runs the {@link ContextBudgetEnforcer} against the conversation
|
|
54
|
+
* history right before the LLM call. Honours the kill-switch in
|
|
55
|
+
* `preferences.resilience.contextBudget`:
|
|
56
|
+
*
|
|
57
|
+
* - `never` — no-op, returns immediately.
|
|
58
|
+
* - `truncate` — runs the enforcer; if it asks for compaction,
|
|
59
|
+
* we skip the LLM call (the next request will
|
|
60
|
+
* likely 413) and let the caller see a smaller
|
|
61
|
+
* prompt.
|
|
62
|
+
* - `auto` — runs the enforcer; if it asks for compaction,
|
|
63
|
+
* we additionally call `ConversationManager.compact`
|
|
64
|
+
* to summarise the oldest turns via the LLM.
|
|
65
|
+
*
|
|
66
|
+
* Returns a short report so callers can log what happened.
|
|
67
|
+
*/
|
|
68
|
+
enforceContextBudget(conversation: ConversationManager, systemPrompt: string, userMessage: string, model: string): Promise<{
|
|
69
|
+
trimmed: boolean;
|
|
70
|
+
compacted: boolean;
|
|
71
|
+
tokensAfter: number;
|
|
72
|
+
}>;
|
|
73
|
+
/** Proxy health check passthrough. */
|
|
74
|
+
ping(): Promise<boolean>;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=single-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"single-agent.d.ts","sourceRoot":"","sources":["../../src/agent/single-agent.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,WAAW,EAAqC,MAAM,mBAAmB,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAIxD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAmB7D,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,eAAO,MAAM,cAAc;;;;mBAqDb,CAAC;kBAAiC,CAAC,cAAe,CAAA;qBAC5D,CAAJ;;;CAjDC,CAAC;AACF,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AA2BrC,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAiC1E;AAkJD,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAS;gBAEb,OAAO,UAAQ;IAM3B,2EAA2E;IAC3E,SAAS,IAAI,WAAW;IAIlB,YAAY,CAChB,OAAO,EAAE,YAAY,EACrB,YAAY,EAAE,mBAAmB,EACjC,EAAE,CAAC,EAAE,QAAQ,CAAC,SAAS,GACtB,OAAO,CAAC,WAAW,CAAC;IAsYvB;;;;;;;;OAQG;YACW,aAAa;IAuD3B;;;;;;;OAOG;YACW,cAAc;YA0Cd,qBAAqB;IAqCnC;;;OAGG;YACW,mBAAmB;IA2BjC;;;;;;;;;;;;;;;;;OAiBG;IACG,oBAAoB,CACxB,YAAY,EAAE,mBAAmB,EACjC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAyCzE,sCAAsC;IAChC,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;CAG/B"}
|